mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
17
Makefile
17
Makefile
@@ -7,17 +7,17 @@ LUA_CLIB_PATH ?= luaclib
|
|||||||
CSERVICE_PATH ?= cservice
|
CSERVICE_PATH ?= cservice
|
||||||
SKYNET_BUILD_PATH ?= .
|
SKYNET_BUILD_PATH ?= .
|
||||||
|
|
||||||
CFLAGS = -g -Wall -I$(LUA_INC) $(MYCFLAGS)
|
CFLAGS = -g -O2 -Wall -I$(LUA_INC) $(MYCFLAGS)
|
||||||
|
|
||||||
$(LUA_STATICLIB) :
|
$(LUA_STATICLIB) :
|
||||||
cd 3rd/lua && $(MAKE) CC=$(CC) $(PLAT)
|
cd 3rd/lua && $(MAKE) CC=$(CC) $(PLAT)
|
||||||
|
|
||||||
CSERVICE = snlua logger gate master multicast tunnel harbor localcast
|
CSERVICE = snlua logger gate master harbor
|
||||||
LUA_CLIB = skynet socketdriver int64 mcast bson mongo md5 netpack cjson clientsocket
|
LUA_CLIB = skynet socketdriver int64 bson mongo md5 netpack cjson clientsocket
|
||||||
|
|
||||||
SKYNET_SRC = skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c \
|
SKYNET_SRC = skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c \
|
||||||
skynet_server.c skynet_start.c skynet_timer.c skynet_error.c \
|
skynet_server.c skynet_start.c skynet_timer.c skynet_error.c \
|
||||||
skynet_harbor.c skynet_multicast.c skynet_group.c skynet_env.c \
|
skynet_harbor.c skynet_env.c \
|
||||||
skynet_monitor.c skynet_socket.c socket_server.c
|
skynet_monitor.c skynet_socket.c socket_server.c
|
||||||
|
|
||||||
all : \
|
all : \
|
||||||
@@ -41,17 +41,14 @@ endef
|
|||||||
|
|
||||||
$(foreach v, $(CSERVICE), $(eval $(call CSERVICE_TEMP,$(v))))
|
$(foreach v, $(CSERVICE), $(eval $(call CSERVICE_TEMP,$(v))))
|
||||||
|
|
||||||
$(LUA_CLIB_PATH)/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/trace_service.c lualib-src/timingqueue.c | $(LUA_CLIB_PATH)
|
$(LUA_CLIB_PATH)/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c | $(LUA_CLIB_PATH)
|
||||||
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src -Ilualib-src
|
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src -Ilualib-src
|
||||||
|
|
||||||
$(LUA_CLIB_PATH)/socketdriver.so : lualib-src/lua-socket.c | $(LUA_CLIB_PATH)
|
$(LUA_CLIB_PATH)/socketdriver.so : lualib-src/lua-socket.c | $(LUA_CLIB_PATH)
|
||||||
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src
|
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src
|
||||||
|
|
||||||
$(LUA_CLIB_PATH)/int64.so : 3rd/lua-int64/int64.c | $(LUA_CLIB_PATH)
|
$(LUA_CLIB_PATH)/int64.so : 3rd/lua-int64/int64.c | $(LUA_CLIB_PATH)
|
||||||
$(CC) $(CFLAGS) $(SHARED) -O2 $^ -o $@
|
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
|
||||||
|
|
||||||
$(LUA_CLIB_PATH)/mcast.so : lualib-src/lua-localcast.c | $(LUA_CLIB_PATH)
|
|
||||||
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src
|
|
||||||
|
|
||||||
$(LUA_CLIB_PATH)/bson.so : lualib-src/lua-bson.c | $(LUA_CLIB_PATH)
|
$(LUA_CLIB_PATH)/bson.so : lualib-src/lua-bson.c | $(LUA_CLIB_PATH)
|
||||||
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
|
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
|
||||||
@@ -60,7 +57,7 @@ $(LUA_CLIB_PATH)/mongo.so : lualib-src/lua-mongo.c | $(LUA_CLIB_PATH)
|
|||||||
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
|
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
|
||||||
|
|
||||||
$(LUA_CLIB_PATH)/md5.so : 3rd/lua-md5/md5.c 3rd/lua-md5/md5lib.c 3rd/lua-md5/compat-5.2.c | $(LUA_CLIB_PATH)
|
$(LUA_CLIB_PATH)/md5.so : 3rd/lua-md5/md5.c 3rd/lua-md5/md5lib.c 3rd/lua-md5/compat-5.2.c | $(LUA_CLIB_PATH)
|
||||||
$(CC) $(CFLAGS) $(SHARED) -O2 -I3rd/lua-md5 $^ -o $@
|
$(CC) $(CFLAGS) $(SHARED) -I3rd/lua-md5 $^ -o $@
|
||||||
|
|
||||||
$(LUA_CLIB_PATH)/netpack.so : lualib-src/lua-netpack.c | $(LUA_CLIB_PATH)
|
$(LUA_CLIB_PATH)/netpack.so : lualib-src/lua-netpack.c | $(LUA_CLIB_PATH)
|
||||||
$(CC) $(CFLAGS) $(SHARED) $^ -Iskynet-src -o $@
|
$(CC) $(CFLAGS) $(SHARED) $^ -Iskynet-src -o $@
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
#include <pthread.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
struct args {
|
|
||||||
int fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
readall(int fd, void * buffer, size_t sz) {
|
|
||||||
for (;;) {
|
|
||||||
int err = recv(fd , buffer, sz, MSG_WAITALL);
|
|
||||||
if (err < 0) {
|
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
perror("Socket error");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
_read(void *ud) {
|
|
||||||
struct args *p = ud;
|
|
||||||
int fd = p->fd;
|
|
||||||
fflush(stdout);
|
|
||||||
for (;;) {
|
|
||||||
uint8_t header[2];
|
|
||||||
fflush(stdout);
|
|
||||||
if (readall(fd, header, 2) == 0)
|
|
||||||
break;
|
|
||||||
size_t len = header[0] << 8 | header[1];
|
|
||||||
if (len>0) {
|
|
||||||
char tmp[len+1];
|
|
||||||
readall(fd, tmp, len);
|
|
||||||
tmp[len]='\0';
|
|
||||||
printf("%s\n",tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
test(void *ud) {
|
|
||||||
struct args *p = ud;
|
|
||||||
int fd = p->fd;
|
|
||||||
|
|
||||||
char tmp[1024];
|
|
||||||
while (!feof(stdin)) {
|
|
||||||
fgets(tmp,sizeof(tmp),stdin);
|
|
||||||
int n = strlen(tmp) -1;
|
|
||||||
uint8_t head[2];
|
|
||||||
head[0] = (n >> 8) & 0xff;
|
|
||||||
head[1] = n & 0xff;
|
|
||||||
int r;
|
|
||||||
r = send(fd, head, 2, 0);
|
|
||||||
if (r<0) {
|
|
||||||
perror("send head");
|
|
||||||
}
|
|
||||||
r = send(fd, tmp , n, 0);
|
|
||||||
if (r<0) {
|
|
||||||
perror("send data");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char * argv[]) {
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("connect address port\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = socket(AF_INET,SOCK_STREAM,0);
|
|
||||||
struct sockaddr_in my_addr;
|
|
||||||
|
|
||||||
my_addr.sin_addr.s_addr=inet_addr(argv[1]);
|
|
||||||
my_addr.sin_family=AF_INET;
|
|
||||||
my_addr.sin_port=htons(strtol(argv[2],NULL,10));
|
|
||||||
|
|
||||||
int r = connect(fd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
if (r == -1) {
|
|
||||||
perror("Connect failed:");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct args arg = { fd };
|
|
||||||
pthread_t pid ;
|
|
||||||
pthread_create(&pid, NULL, _read, &arg);
|
|
||||||
pthread_t pid_stdin;
|
|
||||||
pthread_create(&pid_stdin, NULL, test, &arg);
|
|
||||||
|
|
||||||
pthread_join(pid, NULL);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -193,7 +193,10 @@ readline_stdin(void * arg) {
|
|||||||
struct queue * q = arg;
|
struct queue * q = arg;
|
||||||
char tmp[1024];
|
char tmp[1024];
|
||||||
while (!feof(stdin)) {
|
while (!feof(stdin)) {
|
||||||
fgets(tmp,sizeof(tmp),stdin);
|
if (fgets(tmp,sizeof(tmp),stdin) == NULL) {
|
||||||
|
// read stdin failed
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
int n = strlen(tmp) -1;
|
int n = strlen(tmp) -1;
|
||||||
|
|
||||||
char * str = malloc(n+1);
|
char * str = malloc(n+1);
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
#include <lua.h>
|
|
||||||
#include <lauxlib.h>
|
|
||||||
#include "localcast.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
table handles
|
|
||||||
string msg
|
|
||||||
lightuserdata ptr
|
|
||||||
integer sz
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_pack_message(lua_State *L) {
|
|
||||||
luaL_checktype(L,1,LUA_TTABLE);
|
|
||||||
int type = lua_type(L,2);
|
|
||||||
void * msg = NULL;
|
|
||||||
size_t sz = 0;
|
|
||||||
switch(type) {
|
|
||||||
case LUA_TSTRING: {
|
|
||||||
const char * str = lua_tolstring(L,2,&sz);
|
|
||||||
msg = malloc(sz);
|
|
||||||
memcpy(msg, str, sz);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUA_TLIGHTUSERDATA:
|
|
||||||
msg = lua_touserdata(L,2);
|
|
||||||
sz = luaL_checkinteger(L,3);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
luaL_error(L, "type error : %s", lua_typename(L,type));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
struct localcast *lc = malloc(sizeof(struct localcast));
|
|
||||||
lc->n = lua_rawlen(L,1);
|
|
||||||
uint32_t *group = malloc(lc->n * sizeof(uint32_t));
|
|
||||||
int i;
|
|
||||||
for (i=0;i<lc->n;i++) {
|
|
||||||
lua_rawgeti(L,1,i+1);
|
|
||||||
group[i] = lua_tounsigned(L,-1);
|
|
||||||
lua_pop(L,1);
|
|
||||||
}
|
|
||||||
lc->msg = msg;
|
|
||||||
lc->sz = sz;
|
|
||||||
lc->group = group;
|
|
||||||
lua_pushlightuserdata(L,lc);
|
|
||||||
lua_pushinteger(L, sizeof(*lc));
|
|
||||||
return 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
luaopen_mcast_c(lua_State *L) {
|
|
||||||
luaL_checkversion(L);
|
|
||||||
lua_pushcfunction(L, _pack_message);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "skynet.h"
|
#include "skynet.h"
|
||||||
#include "trace_service.h"
|
|
||||||
#include "lua-seri.h"
|
#include "lua-seri.h"
|
||||||
#include "service_lua.h"
|
#include "service_lua.h"
|
||||||
#include "timingqueue.h"
|
|
||||||
|
|
||||||
#define KNRM "\x1B[0m"
|
#define KNRM "\x1B[0m"
|
||||||
#define KRED "\x1B[31m"
|
#define KRED "\x1B[31m"
|
||||||
@@ -12,89 +10,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <mach/task.h>
|
|
||||||
#include <mach/mach.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct stat {
|
|
||||||
lua_State *L;
|
|
||||||
int count;
|
|
||||||
uint32_t ti_sec;
|
|
||||||
uint32_t ti_nsec;
|
|
||||||
struct trace_pool *trace;
|
|
||||||
struct tqueue * tq;
|
|
||||||
struct snlua *lua;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
_stat_begin(struct stat *S, struct timespec *ti) {
|
|
||||||
S->count++;
|
|
||||||
current_time(ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void
|
|
||||||
_stat_end(struct stat *S, struct timespec *ti) {
|
|
||||||
diff_time(ti, &S->ti_sec, &S->ti_nsec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_stat(lua_State *L) {
|
|
||||||
lua_rawgetp(L, LUA_REGISTRYINDEX, _stat);
|
|
||||||
struct stat *S = lua_touserdata(L,-1);
|
|
||||||
if (S==NULL) {
|
|
||||||
luaL_error(L, "set callback first");
|
|
||||||
}
|
|
||||||
const char * what = luaL_checkstring(L,1);
|
|
||||||
if (strcmp(what,"count")==0) {
|
|
||||||
lua_pushinteger(L, S->count);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (strcmp(what,"time")==0) {
|
|
||||||
double t = (double)S->ti_sec + (double)S->ti_nsec / NANOSEC;
|
|
||||||
lua_pushnumber(L, t);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (strcmp(what,"trace")==0) {
|
|
||||||
lua_pushlightuserdata(L, S->trace);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double
|
|
||||||
current_time_tick(struct stat *S) {
|
|
||||||
return (double)S->ti_sec + (double)S->ti_nsec / NANOSEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct stat *
|
|
||||||
get_stat(lua_State *L) {
|
|
||||||
struct stat * S = lua_touserdata(L, lua_upvalueindex(2));
|
|
||||||
if (S == NULL) {
|
|
||||||
lua_rawgetp(L, LUA_REGISTRYINDEX, _stat);
|
|
||||||
S = lua_touserdata(L, -1);
|
|
||||||
lua_replace(L, lua_upvalueindex(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
return S;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
save_session(lua_State *L, int type, int session) {
|
|
||||||
if (session > 0 && (type & 0xff) != PTYPE_RESPONSE) {
|
|
||||||
struct stat * S = get_stat(L);
|
|
||||||
tqueue_push(S->tq, session, current_time_tick(S));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
|
_cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
|
||||||
struct stat *S = ud;
|
lua_State *L = ud;
|
||||||
lua_State *L = S->L;
|
|
||||||
struct timespec ti;
|
|
||||||
_stat_begin(S, &ti);
|
|
||||||
int trace = 1;
|
int trace = 1;
|
||||||
int r;
|
int r;
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
@@ -111,45 +30,9 @@ _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t
|
|||||||
lua_pushinteger(L, session);
|
lua_pushinteger(L, session);
|
||||||
lua_pushnumber(L, source);
|
lua_pushnumber(L, source);
|
||||||
|
|
||||||
if (type == PTYPE_RESPONSE && session > 0) {
|
r = lua_pcall(L, 5, 0 , trace);
|
||||||
double t = tqueue_pop(S->tq, session);
|
|
||||||
if (t != 0) {
|
|
||||||
t = current_time_tick(S) - t;
|
|
||||||
lua_pushnumber(L, t);
|
|
||||||
r = lua_pcall(L, 6, 0 , trace);
|
|
||||||
} else {
|
|
||||||
r = lua_pcall(L, 5, 0 , trace);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r = lua_pcall(L, 5, 0 , trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
_stat_end(S, &ti);
|
|
||||||
|
|
||||||
struct trace_info *tti = trace_yield(S->trace);
|
|
||||||
if (tti) {
|
|
||||||
skynet_error(context, "Untraced time %f", trace_delete(S->trace, tti));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r == LUA_OK) {
|
if (r == LUA_OK) {
|
||||||
if (S->lua->reload) {
|
|
||||||
skynet_callback(context, NULL, 0);
|
|
||||||
struct snlua * lua = S->lua;
|
|
||||||
assert(lua->L == L);
|
|
||||||
const char * cmd = lua->reload;
|
|
||||||
lua->reload = NULL;
|
|
||||||
lua->L = luaL_newstate();
|
|
||||||
int err = lua->init(lua, context, cmd);
|
|
||||||
if (err) {
|
|
||||||
skynet_callback(context, S, _cb);
|
|
||||||
skynet_error(context, "lua reload failed : %s", cmd);
|
|
||||||
lua_close(lua->L);
|
|
||||||
lua->L = L;
|
|
||||||
} else {
|
|
||||||
skynet_error(context, "lua reload %s", cmd);
|
|
||||||
lua_close(L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const char * self = skynet_command(context, "REG", NULL);
|
const char * self = skynet_command(context, "REG", NULL);
|
||||||
@@ -173,34 +56,9 @@ _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_timing(lua_State *L) {
|
|
||||||
int session = luaL_checkinteger(L,1);
|
|
||||||
struct stat * S = get_stat(L);
|
|
||||||
double t = tqueue_pop(S->tq, session);
|
|
||||||
if (t != 0) {
|
|
||||||
t = current_time_tick(S) - t;
|
|
||||||
}
|
|
||||||
lua_pushnumber(L, t);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_delete_stat(lua_State *L) {
|
|
||||||
struct stat * S = lua_touserdata(L,1);
|
|
||||||
trace_release(S->trace);
|
|
||||||
tqueue_delete(S->tq);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_callback(lua_State *L) {
|
_callback(lua_State *L) {
|
||||||
struct snlua *lua = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
if (lua == NULL || lua->ctx == NULL) {
|
|
||||||
return luaL_error(L, "Init skynet context first");
|
|
||||||
}
|
|
||||||
struct skynet_context * context = lua->ctx;
|
|
||||||
|
|
||||||
luaL_checktype(L,1,LUA_TFUNCTION);
|
luaL_checktype(L,1,LUA_TFUNCTION);
|
||||||
lua_settop(L,1);
|
lua_settop(L,1);
|
||||||
@@ -209,21 +67,7 @@ _callback(lua_State *L) {
|
|||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
|
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
|
||||||
lua_State *gL = lua_tothread(L,-1);
|
lua_State *gL = lua_tothread(L,-1);
|
||||||
|
|
||||||
struct stat * S = lua_newuserdata(L, sizeof(*S));
|
skynet_callback(context, gL, _cb);
|
||||||
memset(S, 0, sizeof(*S));
|
|
||||||
S->L = gL;
|
|
||||||
S->trace = trace_create();
|
|
||||||
S->tq = tqueue_new();
|
|
||||||
S->lua = lua;
|
|
||||||
|
|
||||||
lua_createtable(L,0,1);
|
|
||||||
lua_pushcfunction(L, _delete_stat);
|
|
||||||
lua_setfield(L,-2,"__gc");
|
|
||||||
lua_setmetatable(L, -2);
|
|
||||||
|
|
||||||
lua_rawsetp(L, LUA_REGISTRYINDEX, _stat);
|
|
||||||
|
|
||||||
skynet_callback(context, S, _cb);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -272,19 +116,16 @@ _sendname(lua_State *L, struct skynet_context * context, const char * dest) {
|
|||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
void * msg = (void *)lua_tolstring(L,4,&len);
|
void * msg = (void *)lua_tolstring(L,4,&len);
|
||||||
session = skynet_sendname(context, dest, type, session , msg, len);
|
session = skynet_sendname(context, dest, type, session , msg, len);
|
||||||
save_session(L, type, session);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TNIL :
|
case LUA_TNIL :
|
||||||
session = skynet_sendname(context, dest, type, session , NULL, 0);
|
session = skynet_sendname(context, dest, type, session , NULL, 0);
|
||||||
save_session(L, type, session);
|
|
||||||
break;
|
break;
|
||||||
case LUA_TLIGHTUSERDATA: {
|
case LUA_TLIGHTUSERDATA: {
|
||||||
luaL_checktype(L, 4, LUA_TLIGHTUSERDATA);
|
luaL_checktype(L, 4, LUA_TLIGHTUSERDATA);
|
||||||
void * msg = lua_touserdata(L,4);
|
void * msg = lua_touserdata(L,4);
|
||||||
int size = luaL_checkinteger(L,5);
|
int size = luaL_checkinteger(L,5);
|
||||||
session = skynet_sendname(context, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
session = skynet_sendname(context, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
||||||
save_session(L, type, session);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -350,14 +191,12 @@ _send(lua_State *L) {
|
|||||||
msg = NULL;
|
msg = NULL;
|
||||||
}
|
}
|
||||||
session = skynet_send(context, 0, dest, type, session , msg, len);
|
session = skynet_send(context, 0, dest, type, session , msg, len);
|
||||||
save_session(L, type, session);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TLIGHTUSERDATA: {
|
case LUA_TLIGHTUSERDATA: {
|
||||||
void * msg = lua_touserdata(L,4);
|
void * msg = lua_touserdata(L,4);
|
||||||
int size = luaL_checkinteger(L,5);
|
int size = luaL_checkinteger(L,5);
|
||||||
session = skynet_send(context, 0, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
session = skynet_send(context, 0, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
||||||
save_session(L, type, session);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -389,14 +228,12 @@ _redirect(lua_State *L) {
|
|||||||
msg = NULL;
|
msg = NULL;
|
||||||
}
|
}
|
||||||
session = skynet_send(context, source, dest, type, session , msg, len);
|
session = skynet_send(context, source, dest, type, session , msg, len);
|
||||||
save_session(L, type, session);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TLIGHTUSERDATA: {
|
case LUA_TLIGHTUSERDATA: {
|
||||||
void * msg = lua_touserdata(L,5);
|
void * msg = lua_touserdata(L,5);
|
||||||
int size = luaL_checkinteger(L,6);
|
int size = luaL_checkinteger(L,6);
|
||||||
session = skynet_send(context, source, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
session = skynet_send(context, source, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
||||||
save_session(L, type, session);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -405,15 +242,6 @@ _redirect(lua_State *L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_forward(lua_State *L) {
|
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
|
||||||
uint32_t dest = luaL_checkunsigned(L,1);
|
|
||||||
skynet_forward(context, dest);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_error(lua_State *L) {
|
_error(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
@@ -444,75 +272,6 @@ _harbor(lua_State *L) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_context(lua_State *L) {
|
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
|
||||||
lua_pushlightuserdata(L, context);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trace api
|
|
||||||
static int
|
|
||||||
_trace_new(lua_State *L) {
|
|
||||||
struct trace_pool *p = lua_touserdata(L,1);
|
|
||||||
struct trace_info *t = trace_new(p);
|
|
||||||
if (t==NULL) {
|
|
||||||
return luaL_error(L, "Last trace didn't close");
|
|
||||||
}
|
|
||||||
lua_pushlightuserdata(L,t);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_trace_delete(lua_State *L) {
|
|
||||||
struct trace_pool *p = lua_touserdata(L,1);
|
|
||||||
struct trace_info *t = lua_touserdata(L,2);
|
|
||||||
double ti = trace_delete(p,t);
|
|
||||||
lua_pushnumber(L, ti);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_trace_switch(lua_State *L) {
|
|
||||||
int session = luaL_checkinteger(L,2);
|
|
||||||
if (session <=0)
|
|
||||||
return 0;
|
|
||||||
struct trace_pool *p = lua_touserdata(L,1);
|
|
||||||
trace_switch(p, session);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_trace_yield(lua_State *L) {
|
|
||||||
struct trace_pool *p = lua_touserdata(L,1);
|
|
||||||
struct trace_info * t = trace_yield(p);
|
|
||||||
if (t) {
|
|
||||||
lua_pushlightuserdata(L,t);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_trace_register(lua_State *L) {
|
|
||||||
int session = luaL_checkinteger(L,2);
|
|
||||||
if (session <=0)
|
|
||||||
return 0;
|
|
||||||
struct trace_pool *p = lua_touserdata(L,1);
|
|
||||||
trace_register(p, session);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_reload(lua_State *L) {
|
|
||||||
struct snlua *lua = lua_touserdata(L,lua_upvalueindex(1));
|
|
||||||
lua->reload = luaL_checkstring(L,1);
|
|
||||||
lua_settop(L,1);
|
|
||||||
lua_replace(L,lua_upvalueindex(2));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
luaopen_skynet_c(lua_State *L) {
|
luaopen_skynet_c(lua_State *L) {
|
||||||
luaL_checkversion(L);
|
luaL_checkversion(L);
|
||||||
@@ -520,31 +279,17 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
luaL_Reg l[] = {
|
luaL_Reg l[] = {
|
||||||
{ "send" , _send },
|
{ "send" , _send },
|
||||||
{ "genid", _genid },
|
{ "genid", _genid },
|
||||||
{ "timing", _timing },
|
|
||||||
{ "redirect", _redirect },
|
{ "redirect", _redirect },
|
||||||
{ "forward", _forward },
|
|
||||||
{ "command" , _command },
|
{ "command" , _command },
|
||||||
{ "error", _error },
|
{ "error", _error },
|
||||||
{ "tostring", _tostring },
|
{ "tostring", _tostring },
|
||||||
{ "harbor", _harbor },
|
{ "harbor", _harbor },
|
||||||
{ "context", _context },
|
|
||||||
{ "pack", _luaseri_pack },
|
{ "pack", _luaseri_pack },
|
||||||
{ "unpack", _luaseri_unpack },
|
{ "unpack", _luaseri_unpack },
|
||||||
|
{ "callback", _callback },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
luaL_Reg l2[] = {
|
|
||||||
{ "stat", _stat },
|
|
||||||
{ "trace_new", _trace_new },
|
|
||||||
{ "trace_delete", _trace_delete },
|
|
||||||
{ "trace_switch", _trace_switch },
|
|
||||||
{ "trace_yield", _trace_yield },
|
|
||||||
{ "trace_register", _trace_register },
|
|
||||||
{ NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
lua_createtable(L, 0, (sizeof(l) + sizeof(l2))/sizeof(luaL_Reg)-2);
|
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_lua");
|
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_lua");
|
||||||
struct snlua *lua = lua_touserdata(L,-1);
|
struct snlua *lua = lua_touserdata(L,-1);
|
||||||
if (lua == NULL || lua->ctx == NULL) {
|
if (lua == NULL || lua->ctx == NULL) {
|
||||||
@@ -552,19 +297,9 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
}
|
}
|
||||||
assert(lua->L == L);
|
assert(lua->L == L);
|
||||||
|
|
||||||
lua_pushvalue(L,-1);
|
luaL_newlibtable(L, l);
|
||||||
lua_pushcclosure(L,_callback,1);
|
|
||||||
lua_setfield(L, -3, "callback");
|
|
||||||
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushcclosure(L,_reload,2);
|
|
||||||
lua_setfield(L, -2, "reload");
|
|
||||||
|
|
||||||
lua_pushlightuserdata(L, lua->ctx);
|
lua_pushlightuserdata(L, lua->ctx);
|
||||||
lua_pushnil(L);
|
luaL_setfuncs(L,l,1);
|
||||||
luaL_setfuncs(L,l,2);
|
|
||||||
|
|
||||||
luaL_setfuncs(L,l2,0);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,197 +0,0 @@
|
|||||||
#include "timingqueue.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define INIT_CAP 8
|
|
||||||
|
|
||||||
struct session_time {
|
|
||||||
int session;
|
|
||||||
double time;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tqueue {
|
|
||||||
int cap;
|
|
||||||
int n;
|
|
||||||
int head;
|
|
||||||
int tail;
|
|
||||||
struct session_time * q;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tqueue *
|
|
||||||
tqueue_new() {
|
|
||||||
struct tqueue * tq = malloc(sizeof(*tq));
|
|
||||||
tq->cap = INIT_CAP;
|
|
||||||
tq->head = 0;
|
|
||||||
tq->tail = 0;
|
|
||||||
tq->n = 0;
|
|
||||||
tq->q = malloc(sizeof(struct session_time) * tq->cap);
|
|
||||||
return tq;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tqueue_delete(struct tqueue *tq) {
|
|
||||||
free(tq->q);
|
|
||||||
free(tq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct session_time *
|
|
||||||
expand_queue(struct tqueue *tq) {
|
|
||||||
if (tq->n == tq->cap) {
|
|
||||||
struct session_time * q = malloc(sizeof(*q) * tq->cap * 2);
|
|
||||||
int i;
|
|
||||||
for (i=0;i<tq->cap;i++) {
|
|
||||||
int index = tq->head + i;
|
|
||||||
if (index >= tq->cap) {
|
|
||||||
index -= tq->cap;
|
|
||||||
}
|
|
||||||
q[i] = tq->q[index];
|
|
||||||
}
|
|
||||||
tq->head = 0;
|
|
||||||
tq->tail = tq->cap;
|
|
||||||
tq->cap *= 2;
|
|
||||||
free(tq->q);
|
|
||||||
tq->q = q;
|
|
||||||
return &q[tq->tail-1];
|
|
||||||
} else {
|
|
||||||
int i;
|
|
||||||
for (i=0;i<tq->cap-1;i++) {
|
|
||||||
int index = tq->head + i;
|
|
||||||
if (index >= tq->cap) {
|
|
||||||
index -= tq->cap;
|
|
||||||
}
|
|
||||||
if (tq->q[index].session == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int p = i + tq->head;
|
|
||||||
if (p >= tq->cap)
|
|
||||||
p -= tq->cap;
|
|
||||||
for (++i;i<tq->cap-1;i++) {
|
|
||||||
int index = tq->head + i;
|
|
||||||
if (index >= tq->cap) {
|
|
||||||
index -= tq->cap;
|
|
||||||
}
|
|
||||||
if (tq->q[index].session == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tq->q[p] = tq->q[index];
|
|
||||||
++ p;
|
|
||||||
if (p >= tq->cap) {
|
|
||||||
p -= tq->cap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tq->tail = p + 1;
|
|
||||||
if (tq->tail >= tq->cap) {
|
|
||||||
tq->tail -= tq->cap;
|
|
||||||
}
|
|
||||||
return &tq->q[p];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct session_time *
|
|
||||||
last_one(struct tqueue * tq, struct session_time *current) {
|
|
||||||
--current;
|
|
||||||
if (current < tq->q) {
|
|
||||||
return &tq->q[tq->cap-1];
|
|
||||||
}
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tqueue_push(struct tqueue *tq, int session, double time) {
|
|
||||||
assert(session !=0);
|
|
||||||
++ tq->n;
|
|
||||||
if (tq->head == tq->tail) {
|
|
||||||
// queue is empty;
|
|
||||||
tq->head = 0;
|
|
||||||
tq->tail = 1;
|
|
||||||
tq->q[0].session = session;
|
|
||||||
tq->q[0].time = time;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct session_time * st = &tq->q[tq->tail++];
|
|
||||||
if (tq->tail >= tq->cap) {
|
|
||||||
tq->tail = 0;
|
|
||||||
}
|
|
||||||
if (tq->tail == tq->head) {
|
|
||||||
st = expand_queue(tq);
|
|
||||||
}
|
|
||||||
st->session = session;
|
|
||||||
st->time = time;
|
|
||||||
|
|
||||||
// session must great than last one
|
|
||||||
int i;
|
|
||||||
for (i=1;i<tq->n;i++) {
|
|
||||||
struct session_time *last = last_one(tq, st);
|
|
||||||
if (session > last->session)
|
|
||||||
return;
|
|
||||||
// swap st, last
|
|
||||||
struct session_time temp = *last;
|
|
||||||
*last = *st;
|
|
||||||
*st = temp;
|
|
||||||
|
|
||||||
st = last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
tqueue_pop(struct tqueue *tq, int session) {
|
|
||||||
if (tq->head == tq->tail) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (session == tq->q[tq->head].session) {
|
|
||||||
--tq->n;
|
|
||||||
double ret = tq->q[tq->head].time;
|
|
||||||
do {
|
|
||||||
++tq->head;
|
|
||||||
if (tq->head == tq->cap) {
|
|
||||||
tq->head = 0;
|
|
||||||
}
|
|
||||||
} while (tq->head != tq->tail && tq->q[tq->head].session == 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
// binary search session
|
|
||||||
int n = tq->tail - tq->head;
|
|
||||||
if (n < 0) {
|
|
||||||
n += tq->cap;
|
|
||||||
}
|
|
||||||
int begin = 1;
|
|
||||||
int end = n;
|
|
||||||
while (begin < end) {
|
|
||||||
int mid = (begin + end)/2;
|
|
||||||
int index = mid + tq->head;
|
|
||||||
if (index >= tq->cap) {
|
|
||||||
index -= tq->cap;
|
|
||||||
}
|
|
||||||
struct session_time *st = &tq->q[index];
|
|
||||||
if (st->session == session) {
|
|
||||||
--tq->n;
|
|
||||||
st->session = 0;
|
|
||||||
return st->time;
|
|
||||||
}
|
|
||||||
if (session > st->session) {
|
|
||||||
begin = mid + 1;
|
|
||||||
} else {
|
|
||||||
end = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// not found
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tqueue_dump(struct tqueue *tq) {
|
|
||||||
printf("cap = %d, head = %d, tail = %d, n = %d\n",
|
|
||||||
tq->cap, tq->head, tq->tail, tq->n);
|
|
||||||
int head = tq->head;
|
|
||||||
while (head!=tq->tail) {
|
|
||||||
struct session_time *st = &tq->q[head];
|
|
||||||
if (st->session != 0) {
|
|
||||||
printf("%d : %f\n", st->session, st->time);
|
|
||||||
}
|
|
||||||
++ head;
|
|
||||||
if (head >= tq->cap)
|
|
||||||
head -= tq->cap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#ifndef skynet_timing_queue_h
|
|
||||||
#define skynet_timing_queue_h
|
|
||||||
|
|
||||||
struct tqueue * tqueue_new();
|
|
||||||
void tqueue_delete(struct tqueue *);
|
|
||||||
|
|
||||||
void tqueue_push(struct tqueue *, int session, double time);
|
|
||||||
double tqueue_pop(struct tqueue *, int session);
|
|
||||||
|
|
||||||
// for debug
|
|
||||||
void tqueue_dump(struct tqueue *tq);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
#include "trace_service.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define HASH_SIZE 32
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <mach/task.h>
|
|
||||||
#include <mach/mach.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
current_time(struct timespec *ti) {
|
|
||||||
#if !defined(__APPLE__)
|
|
||||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, ti);
|
|
||||||
#else
|
|
||||||
struct task_thread_times_info aTaskInfo;
|
|
||||||
mach_msg_type_number_t aTaskInfoCount = TASK_THREAD_TIMES_INFO_COUNT;
|
|
||||||
assert(KERN_SUCCESS == task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t )&aTaskInfo, &aTaskInfoCount));
|
|
||||||
ti->tv_sec = aTaskInfo.user_time.seconds;
|
|
||||||
ti->tv_nsec = aTaskInfo.user_time.microseconds * 1000;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
diff_time(struct timespec *ti, uint32_t *sec, uint32_t *nsec) {
|
|
||||||
struct timespec end;
|
|
||||||
current_time(&end);
|
|
||||||
int diffsec = end.tv_sec - ti->tv_sec;
|
|
||||||
assert(diffsec>=0);
|
|
||||||
int diffnsec = end.tv_nsec - ti->tv_nsec;
|
|
||||||
if (diffnsec < 0) {
|
|
||||||
--diffsec;
|
|
||||||
diffnsec += NANOSEC;
|
|
||||||
}
|
|
||||||
*nsec += diffnsec;
|
|
||||||
if (*nsec > NANOSEC) {
|
|
||||||
++*sec;
|
|
||||||
*nsec -= NANOSEC;
|
|
||||||
}
|
|
||||||
*sec += diffsec;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct trace_info {
|
|
||||||
int session;
|
|
||||||
struct trace_info * prev;
|
|
||||||
struct trace_info * next;
|
|
||||||
struct timespec ti;
|
|
||||||
uint32_t ti_sec;
|
|
||||||
uint32_t ti_nsec;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct trace_pool {
|
|
||||||
struct trace_info * current;
|
|
||||||
struct trace_info * slot[HASH_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct trace_pool *
|
|
||||||
trace_create() {
|
|
||||||
struct trace_pool * p = malloc(sizeof(*p));
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_free_slot(struct trace_info *t) {
|
|
||||||
while (t) {
|
|
||||||
struct trace_info *next = t->next;
|
|
||||||
free(t);
|
|
||||||
t = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
trace_release(struct trace_pool *p) {
|
|
||||||
int i;
|
|
||||||
for (i=0;i<HASH_SIZE;i++) {
|
|
||||||
_free_slot(p->slot[i]);
|
|
||||||
}
|
|
||||||
free(p->current);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct trace_info *
|
|
||||||
trace_new(struct trace_pool *p) {
|
|
||||||
if (p->current) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct trace_info *t = malloc(sizeof(*t));
|
|
||||||
p->current = t;
|
|
||||||
t->session = 0;
|
|
||||||
t->prev = NULL;
|
|
||||||
t->next = NULL;
|
|
||||||
t->ti_sec = 0;
|
|
||||||
t->ti_nsec = 0;
|
|
||||||
current_time(&t->ti);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
trace_register(struct trace_pool *p, int session) {
|
|
||||||
struct trace_info *t = p->current;
|
|
||||||
if (t == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int hash = session % HASH_SIZE;
|
|
||||||
assert(t->session == 0 && session > 0);
|
|
||||||
t->session = session;
|
|
||||||
t->prev = NULL;
|
|
||||||
t->next = p->slot[hash];
|
|
||||||
if (p->slot[hash]) {
|
|
||||||
p->slot[hash]->prev = t;
|
|
||||||
}
|
|
||||||
p->slot[hash] = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct trace_info *
|
|
||||||
trace_yield(struct trace_pool *p) {
|
|
||||||
struct trace_info *t = p->current;
|
|
||||||
if (t == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
diff_time(&t->ti,&t->ti_sec,&t->ti_nsec);
|
|
||||||
|
|
||||||
if (t->session == 0) {
|
|
||||||
return t;
|
|
||||||
} else {
|
|
||||||
p->current = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
trace_switch(struct trace_pool *p, int session) {
|
|
||||||
assert(p->current == NULL && session > 0);
|
|
||||||
struct trace_info *t = p->slot[session % HASH_SIZE];
|
|
||||||
struct trace_info *prev = NULL;
|
|
||||||
while (t) {
|
|
||||||
if (t->session == session) {
|
|
||||||
p->current = t;
|
|
||||||
t->session = 0;
|
|
||||||
if (prev == NULL) {
|
|
||||||
p->slot[session % HASH_SIZE] = t->next;
|
|
||||||
} else {
|
|
||||||
prev->next = t->next;
|
|
||||||
}
|
|
||||||
if (t->next) {
|
|
||||||
t->next->prev = prev;
|
|
||||||
}
|
|
||||||
current_time(&t->ti);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prev = t;
|
|
||||||
t=t->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
trace_delete(struct trace_pool *p, struct trace_info *t) {
|
|
||||||
assert(p->current == t);
|
|
||||||
p->current = NULL;
|
|
||||||
if (t) {
|
|
||||||
double ti = (double)t->ti_sec + (double)t->ti_nsec / NANOSEC;
|
|
||||||
free(t);
|
|
||||||
return ti;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#ifndef TRACE_SERVICE_H
|
|
||||||
#define TRACE_SERVICE_H
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define NANOSEC 1000000000
|
|
||||||
|
|
||||||
void current_time(struct timespec *ti);
|
|
||||||
void diff_time(struct timespec *ti, uint32_t *sec, uint32_t *nsec);
|
|
||||||
|
|
||||||
struct trace_pool;
|
|
||||||
struct trace_info;
|
|
||||||
|
|
||||||
struct trace_pool * trace_create();
|
|
||||||
void trace_release(struct trace_pool *);
|
|
||||||
struct trace_info * trace_new(struct trace_pool *);
|
|
||||||
void trace_register(struct trace_pool *, int session);
|
|
||||||
void trace_switch(struct trace_pool *, int session);
|
|
||||||
struct trace_info * trace_yield(struct trace_pool *);
|
|
||||||
double trace_delete(struct trace_pool *, struct trace_info *);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
require "loadx"
|
|
||||||
|
|
||||||
local function config(path , pre)
|
local function config(path , pre)
|
||||||
assert(path)
|
assert(path)
|
||||||
local env = pre or {}
|
local env = pre or {}
|
||||||
@@ -8,4 +6,4 @@ local function config(path , pre)
|
|||||||
return env
|
return env
|
||||||
end
|
end
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
if _VERSION == "Lua 5.2" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local assert = assert
|
|
||||||
|
|
||||||
assert(_VERSION == "Lua 5.1")
|
|
||||||
|
|
||||||
local setfenv = setfenv
|
|
||||||
local loadstring = loadstring
|
|
||||||
local load = load
|
|
||||||
local io = io
|
|
||||||
|
|
||||||
function _G.load(ld, chunkname, mode, env)
|
|
||||||
local f,err
|
|
||||||
if type(ld) == "string" then
|
|
||||||
f,err = loadstring(ld, chunkname)
|
|
||||||
else
|
|
||||||
f,err = load(ld, chunkname)
|
|
||||||
end
|
|
||||||
if f == nil then
|
|
||||||
assert(f, err)
|
|
||||||
return f, err
|
|
||||||
end
|
|
||||||
if env then
|
|
||||||
setfenv(f, env)
|
|
||||||
end
|
|
||||||
|
|
||||||
return f,err
|
|
||||||
end
|
|
||||||
|
|
||||||
function _G.loadfile(filename, mode, env)
|
|
||||||
local f = io.open(filename, "rb")
|
|
||||||
assert(f, filename)
|
|
||||||
local source = f:read "*a"
|
|
||||||
f:close()
|
|
||||||
return _G.load(source, "@" .. filename, mode, env)
|
|
||||||
end
|
|
||||||
|
|
||||||
_G.loadstring = _G.load
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
local lg
|
|
||||||
|
|
||||||
local group = {}
|
|
||||||
|
|
||||||
function group.create()
|
|
||||||
return skynet.call(lg, "lua", "NEW" , skynet.self())
|
|
||||||
end
|
|
||||||
|
|
||||||
group.address = assert(skynet.query_group)
|
|
||||||
group.enter = assert(skynet.enter_group)
|
|
||||||
group.leave = assert(skynet.leave_group)
|
|
||||||
|
|
||||||
function group.release(id)
|
|
||||||
skynet.send(lg, "lua" , "DELETE", id)
|
|
||||||
end
|
|
||||||
|
|
||||||
skynet.init(function()
|
|
||||||
lg = skynet.uniqueservice("group_local")
|
|
||||||
assert(lg)
|
|
||||||
end, "localgroup")
|
|
||||||
|
|
||||||
return group
|
|
||||||
@@ -22,6 +22,7 @@ logger.CRITICAL = 50
|
|||||||
logger.FATAL = 60
|
logger.FATAL = 60
|
||||||
|
|
||||||
local function log_to_disk(...)
|
local function log_to_disk(...)
|
||||||
|
-- implement your .lualog service
|
||||||
Skynet.send(".lualog" , "lua" , ...)
|
Skynet.send(".lualog" , "lua" , ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
local SERVICE
|
|
||||||
|
|
||||||
local group = {}
|
|
||||||
|
|
||||||
function group.create()
|
|
||||||
return skynet.call(SERVICE, "lua", "NEW" , skynet.self())
|
|
||||||
end
|
|
||||||
|
|
||||||
function group.address(id)
|
|
||||||
local send_id = id * 2 + 1
|
|
||||||
return skynet.query_group(send_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
function group.enter(id, handle)
|
|
||||||
handle = handle or skynet.self()
|
|
||||||
skynet.send(SERVICE, "lua" , "ENTER", handle, id)
|
|
||||||
end
|
|
||||||
|
|
||||||
function group.leave(id, handle)
|
|
||||||
handle = handle or skynet.self()
|
|
||||||
skynet.send(SERVICE, "lua" , "LEAVE", handle, id)
|
|
||||||
end
|
|
||||||
|
|
||||||
function group.release(id)
|
|
||||||
skynet.send(SERVICE, "lua" , "DELETE", skynet.self(), id)
|
|
||||||
end
|
|
||||||
|
|
||||||
skynet.init(function()
|
|
||||||
SERVICE = skynet.uniqueservice(true, "group_mgr")
|
|
||||||
skynet.uniqueservice("group_agent", SERVICE)
|
|
||||||
end, "mcgroup")
|
|
||||||
|
|
||||||
return group
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
local c = require "skynet.c"
|
local c = require "skynet.c"
|
||||||
local mc = require "mcast.c"
|
|
||||||
local tostring = tostring
|
local tostring = tostring
|
||||||
local tonumber = tonumber
|
local tonumber = tonumber
|
||||||
local coroutine = coroutine
|
local coroutine = coroutine
|
||||||
@@ -12,7 +11,7 @@ local skynet = {
|
|||||||
-- read skynet.h
|
-- read skynet.h
|
||||||
PTYPE_TEXT = 0,
|
PTYPE_TEXT = 0,
|
||||||
PTYPE_RESPONSE = 1,
|
PTYPE_RESPONSE = 1,
|
||||||
PTYPE_MULTICAST = 2,
|
-- PTYPE_MULTICAST = 2, -- DEPRECATED
|
||||||
PTYPE_CLIENT = 3,
|
PTYPE_CLIENT = 3,
|
||||||
PTYPE_SYSTEM = 4,
|
PTYPE_SYSTEM = 4,
|
||||||
PTYPE_HARBOR = 5,
|
PTYPE_HARBOR = 5,
|
||||||
@@ -46,15 +45,9 @@ local watching_service = {}
|
|||||||
local watching_session = {}
|
local watching_session = {}
|
||||||
local error_queue = {}
|
local error_queue = {}
|
||||||
|
|
||||||
-- timing remote call, turn off by default. Use skynet.timing_call() to turn on.
|
|
||||||
local timing_call = nil
|
|
||||||
|
|
||||||
-- suspend is function
|
-- suspend is function
|
||||||
local suspend
|
local suspend
|
||||||
|
|
||||||
local trace_handle
|
|
||||||
local trace_func = function() end
|
|
||||||
|
|
||||||
local function string_to_handle(str)
|
local function string_to_handle(str)
|
||||||
return tonumber("0x" .. string.sub(str , 2))
|
return tonumber("0x" .. string.sub(str , 2))
|
||||||
end
|
end
|
||||||
@@ -66,7 +59,6 @@ local function dispatch_error_queue()
|
|||||||
if session then
|
if session then
|
||||||
local co = session_id_coroutine[session]
|
local co = session_id_coroutine[session]
|
||||||
session_id_coroutine[session] = nil
|
session_id_coroutine[session] = nil
|
||||||
c.trace_switch(trace_handle, session)
|
|
||||||
return suspend(co, coroutine.resume(co, false))
|
return suspend(co, coroutine.resume(co, false))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -139,18 +131,9 @@ local function dispatch_wakeup()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function trace_count()
|
|
||||||
local info = c.trace_yield(trace_handle)
|
|
||||||
if info then
|
|
||||||
local ti = c.trace_delete(trace_handle, info)
|
|
||||||
trace_func(info, ti)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- suspend is local function
|
-- suspend is local function
|
||||||
function suspend(co, result, command, param, size)
|
function suspend(co, result, command, param, size)
|
||||||
if not result then
|
if not result then
|
||||||
trace_count()
|
|
||||||
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 and session ~= 0 then
|
if session and session ~= 0 then
|
||||||
@@ -161,22 +144,16 @@ function suspend(co, result, command, param, size)
|
|||||||
error(debug.traceback(co,tostring(command)))
|
error(debug.traceback(co,tostring(command)))
|
||||||
end
|
end
|
||||||
if command == "CALL" then
|
if command == "CALL" then
|
||||||
c.trace_register(trace_handle, param)
|
|
||||||
session_id_coroutine[param] = co
|
session_id_coroutine[param] = co
|
||||||
elseif command == "SLEEP" then
|
elseif command == "SLEEP" then
|
||||||
c.trace_register(trace_handle, param)
|
|
||||||
session_id_coroutine[param] = co
|
session_id_coroutine[param] = co
|
||||||
sleep_session[co] = param
|
sleep_session[co] = param
|
||||||
elseif command == "RETURN" then
|
elseif command == "RETURN" then
|
||||||
local co_session = session_coroutine_id[co]
|
local co_session = session_coroutine_id[co]
|
||||||
local co_address = session_coroutine_address[co]
|
local co_address = session_coroutine_address[co]
|
||||||
if param == nil then
|
if param == nil then
|
||||||
trace_count()
|
|
||||||
error(debug.traceback(co))
|
error(debug.traceback(co))
|
||||||
end
|
end
|
||||||
-- c.send maybe throw a error, so call trace_count first.
|
|
||||||
-- The coroutine execute time after skynet.ret() will not be trace.
|
|
||||||
trace_count()
|
|
||||||
c.send(co_address, skynet.PTYPE_RESPONSE, co_session, param, size)
|
c.send(co_address, skynet.PTYPE_RESPONSE, co_session, param, size)
|
||||||
return suspend(co, coroutine.resume(co))
|
return suspend(co, coroutine.resume(co))
|
||||||
elseif command == "EXIT" then
|
elseif command == "EXIT" then
|
||||||
@@ -184,10 +161,8 @@ function suspend(co, result, command, param, size)
|
|||||||
session_coroutine_id[co] = nil
|
session_coroutine_id[co] = nil
|
||||||
session_coroutine_address[co] = nil
|
session_coroutine_address[co] = nil
|
||||||
else
|
else
|
||||||
trace_count()
|
|
||||||
error("Unknown command : " .. command .. "\n" .. debug.traceback(co))
|
error("Unknown command : " .. command .. "\n" .. debug.traceback(co))
|
||||||
end
|
end
|
||||||
trace_count()
|
|
||||||
dispatch_wakeup()
|
dispatch_wakeup()
|
||||||
dispatch_error_queue()
|
dispatch_error_queue()
|
||||||
end
|
end
|
||||||
@@ -208,7 +183,6 @@ function skynet.sleep(ti)
|
|||||||
local succ, ret = coroutine_yield("SLEEP", session)
|
local succ, ret = coroutine_yield("SLEEP", session)
|
||||||
sleep_session[coroutine.running()] = nil
|
sleep_session[coroutine.running()] = nil
|
||||||
if ret == true then
|
if ret == true then
|
||||||
c.trace_switch(trace_handle, session)
|
|
||||||
return "BREAK"
|
return "BREAK"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -220,7 +194,6 @@ end
|
|||||||
function skynet.wait()
|
function skynet.wait()
|
||||||
local session = c.genid()
|
local session = c.genid()
|
||||||
coroutine_yield("SLEEP", session)
|
coroutine_yield("SLEEP", session)
|
||||||
c.trace_switch(trace_handle, session)
|
|
||||||
local co = coroutine.running()
|
local co = coroutine.running()
|
||||||
sleep_session[co] = nil
|
sleep_session[co] = nil
|
||||||
session_id_coroutine[session] = nil
|
session_id_coroutine[session] = nil
|
||||||
@@ -291,15 +264,7 @@ function skynet.send(addr, typename, ...)
|
|||||||
return c.send(addr, p.id, 0 , p.pack(...))
|
return c.send(addr, p.id, 0 , p.pack(...))
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.cast(group, typename, ...)
|
|
||||||
local p = proto[typename]
|
|
||||||
if #group > 0 then
|
|
||||||
return c.send(".cast", p.id, 0, mc(group, p.pack(...)))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
skynet.genid = assert(c.genid)
|
skynet.genid = assert(c.genid)
|
||||||
skynet.forward = assert(c.forward)
|
|
||||||
|
|
||||||
skynet.redirect = function(dest,source,typename,...)
|
skynet.redirect = function(dest,source,typename,...)
|
||||||
return c.redirect(dest, source, proto[typename].id, ...)
|
return c.redirect(dest, source, proto[typename].id, ...)
|
||||||
@@ -387,33 +352,15 @@ function skynet.fork(func,...)
|
|||||||
table.insert(fork_queue, co)
|
table.insert(fork_queue, co)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function timing(session, source, ti)
|
local function raw_dispatch_message(prototype, msg, sz, session, source)
|
||||||
if ti == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local t = timing_call[source]
|
|
||||||
if t == nil then
|
|
||||||
t = { n = 1, ti = ti }
|
|
||||||
timing_call[source] = t
|
|
||||||
else
|
|
||||||
t.n = t.n + 1
|
|
||||||
t.ti = t.ti + ti
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function raw_dispatch_message(prototype, msg, sz, session, source, ...)
|
|
||||||
-- skynet.PTYPE_RESPONSE = 1, read skynet.h
|
-- skynet.PTYPE_RESPONSE = 1, read skynet.h
|
||||||
if prototype == 1 then
|
if prototype == 1 then
|
||||||
if timing_call then
|
|
||||||
timing(session, source, ...)
|
|
||||||
end
|
|
||||||
local co = session_id_coroutine[session]
|
local co = session_id_coroutine[session]
|
||||||
if co == "BREAK" then
|
if co == "BREAK" then
|
||||||
session_id_coroutine[session] = nil
|
session_id_coroutine[session] = nil
|
||||||
elseif co == nil then
|
elseif co == nil then
|
||||||
unknown_response(session, source, msg, sz)
|
unknown_response(session, source, msg, sz)
|
||||||
else
|
else
|
||||||
c.trace_switch(trace_handle, session)
|
|
||||||
session_id_coroutine[session] = nil
|
session_id_coroutine[session] = nil
|
||||||
suspend(co, coroutine.resume(co, true, msg, sz))
|
suspend(co, coroutine.resume(co, true, msg, sz))
|
||||||
end
|
end
|
||||||
@@ -424,7 +371,7 @@ local function raw_dispatch_message(prototype, msg, sz, session, source, ...)
|
|||||||
local co = co_create(f)
|
local co = co_create(f)
|
||||||
session_coroutine_id[co] = session
|
session_coroutine_id[co] = session
|
||||||
session_coroutine_address[co] = source
|
session_coroutine_address[co] = source
|
||||||
suspend(co, coroutine.resume(co, session,source, p.unpack(msg,sz,...)))
|
suspend(co, coroutine.resume(co, session,source, p.unpack(msg,sz)))
|
||||||
else
|
else
|
||||||
print("Unknown request :" , p.unpack(msg,sz))
|
print("Unknown request :" , p.unpack(msg,sz))
|
||||||
error(string.format("Can't dispatch type %s : ", p.name))
|
error(string.format("Can't dispatch type %s : ", p.name))
|
||||||
@@ -493,22 +440,6 @@ local function group_command(cmd, handle, address)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.enter_group(handle , address)
|
|
||||||
c.command("GROUP", group_command("ENTER", handle, address))
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.leave_group(handle , address)
|
|
||||||
c.command("GROUP", group_command("LEAVE", handle, address))
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.clear_group(handle)
|
|
||||||
c.command("GROUP", "CLEAR " .. tostring(handle))
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.query_group(handle)
|
|
||||||
return string_to_handle(c.command("GROUP","QUERY " .. tostring(handle)))
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.address(addr)
|
function skynet.address(addr)
|
||||||
if type(addr) == "number" then
|
if type(addr) == "number" then
|
||||||
return string.format(":%x",addr)
|
return string.format(":%x",addr)
|
||||||
@@ -531,12 +462,6 @@ end
|
|||||||
|
|
||||||
----- debug
|
----- debug
|
||||||
|
|
||||||
local internal_info_func
|
|
||||||
|
|
||||||
function skynet.info_func(func)
|
|
||||||
internal_info_func = func
|
|
||||||
end
|
|
||||||
|
|
||||||
local dbgcmd = {}
|
local dbgcmd = {}
|
||||||
|
|
||||||
function dbgcmd.MEM()
|
function dbgcmd.MEM()
|
||||||
@@ -549,15 +474,8 @@ function dbgcmd.GC()
|
|||||||
collectgarbage "collect"
|
collectgarbage "collect"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function query_state(stat, what)
|
|
||||||
stat[what] = c.stat(what)
|
|
||||||
end
|
|
||||||
|
|
||||||
function dbgcmd.STAT()
|
function dbgcmd.STAT()
|
||||||
local stat = {}
|
local stat = {}
|
||||||
query_state(stat, "count")
|
|
||||||
query_state(stat, "time")
|
|
||||||
stat.boottime = debug.getregistry().skynet_boottime
|
|
||||||
stat.mqlen = skynet.mqlen()
|
stat.mqlen = skynet.mqlen()
|
||||||
skynet.ret(skynet.pack(stat))
|
skynet.ret(skynet.pack(stat))
|
||||||
end
|
end
|
||||||
@@ -570,23 +488,6 @@ function dbgcmd.INFO()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function dbgcmd.TIMING()
|
|
||||||
if timing_call then
|
|
||||||
skynet.ret(skynet.pack(timing_call))
|
|
||||||
-- turn off timing
|
|
||||||
timing_call = nil
|
|
||||||
else
|
|
||||||
-- turn on timing
|
|
||||||
timing_call = {}
|
|
||||||
skynet.ret(skynet.pack(timing_call))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function dbgcmd.RELOAD(...)
|
|
||||||
local cmd = table.concat({...}, " ")
|
|
||||||
c.reload(cmd)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function _debug_dispatch(session, address, cmd, ...)
|
local function _debug_dispatch(session, address, cmd, ...)
|
||||||
local f = dbgcmd[cmd]
|
local f = dbgcmd[cmd]
|
||||||
assert(f, cmd)
|
assert(f, cmd)
|
||||||
@@ -686,7 +587,6 @@ end
|
|||||||
|
|
||||||
function skynet.start(start_func)
|
function skynet.start(start_func)
|
||||||
c.callback(dispatch_message)
|
c.callback(dispatch_message)
|
||||||
trace_handle = assert(c.stat "trace")
|
|
||||||
skynet.timeout(0, function()
|
skynet.timeout(0, function()
|
||||||
init_service(start_func)
|
init_service(start_func)
|
||||||
end)
|
end)
|
||||||
@@ -696,24 +596,11 @@ function skynet.filter(f ,start_func)
|
|||||||
c.callback(function(...)
|
c.callback(function(...)
|
||||||
dispatch_message(f(...))
|
dispatch_message(f(...))
|
||||||
end)
|
end)
|
||||||
trace_handle = assert(c.stat "trace")
|
|
||||||
skynet.timeout(0, function()
|
skynet.timeout(0, function()
|
||||||
init_service(start_func)
|
init_service(start_func)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.trace()
|
|
||||||
return c.trace_new(trace_handle)
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.trace_session(session)
|
|
||||||
return c.trace_register(trace_handle, session)
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.trace_callback(func)
|
|
||||||
trace_func = func
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.endless()
|
function skynet.endless()
|
||||||
return c.command("ENDLESS")~=nil
|
return c.command("ENDLESS")~=nil
|
||||||
end
|
end
|
||||||
@@ -722,10 +609,6 @@ function skynet.abort()
|
|||||||
c.command("ABORT")
|
c.command("ABORT")
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.context_ptr()
|
|
||||||
return c.context()
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.monitor(service, query)
|
function skynet.monitor(service, query)
|
||||||
local monitor
|
local monitor
|
||||||
if query then
|
if query then
|
||||||
@@ -741,14 +624,4 @@ function skynet.mqlen()
|
|||||||
return tonumber(c.command "MQLEN")
|
return tonumber(c.command "MQLEN")
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.timing_call(tc)
|
|
||||||
local ret = timing_call
|
|
||||||
timing_call = tc or {}
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.timing_session(session)
|
|
||||||
return c.timing(session)
|
|
||||||
end
|
|
||||||
|
|
||||||
return skynet
|
return skynet
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
#ifndef SKYNET_LOCAL_CAST_H
|
|
||||||
#define SKYNET_LOCAL_CAST_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct localcast {
|
|
||||||
int n;
|
|
||||||
const uint32_t * group;
|
|
||||||
void *msg;
|
|
||||||
size_t sz;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#include "skynet.h"
|
|
||||||
#include "skynet_handle.h"
|
|
||||||
#include "skynet_multicast.h"
|
|
||||||
#include "localcast.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
_maincb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
|
|
||||||
const struct localcast *lc = msg;
|
|
||||||
size_t s = lc->sz | type << HANDLE_REMOTE_SHIFT;
|
|
||||||
struct skynet_multicast_message * mc = skynet_multicast_create(lc->msg, s, source);
|
|
||||||
skynet_multicast_cast(context, mc, lc->group, lc->n);
|
|
||||||
free((void *)lc->group);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
localcast_init(void * ud, struct skynet_context *ctx, const char * args) {
|
|
||||||
skynet_callback(ctx, ud, _maincb);
|
|
||||||
skynet_command(ctx, "REG", ".cast");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
struct snlua {
|
struct snlua {
|
||||||
lua_State * L;
|
lua_State * L;
|
||||||
const char * reload;
|
|
||||||
struct skynet_context * ctx;
|
struct skynet_context * ctx;
|
||||||
struct tqueue * tq;
|
|
||||||
int (*init)(struct snlua *l, struct skynet_context *ctx, const char * args);
|
int (*init)(struct snlua *l, struct skynet_context *ctx, const char * args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
#include "skynet.h"
|
|
||||||
#include "skynet_handle.h"
|
|
||||||
#include "skynet_multicast.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct skynet_multicast_group *
|
|
||||||
multicast_create() {
|
|
||||||
return skynet_multicast_newgroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
multicast_release(struct skynet_multicast_group *g) {
|
|
||||||
skynet_multicast_deletegroup(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_maincb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
|
|
||||||
struct skynet_multicast_group *g = ud;
|
|
||||||
if (type == PTYPE_SYSTEM) {
|
|
||||||
char cmd = '\0';
|
|
||||||
uint32_t handle = 0;
|
|
||||||
sscanf(msg,"%c %x",&cmd,&handle);
|
|
||||||
if (handle == 0) {
|
|
||||||
skynet_error(context, "Invalid handle %s",msg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
switch (cmd) {
|
|
||||||
case 'E':
|
|
||||||
skynet_multicast_entergroup(g, handle);
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
skynet_multicast_leavegroup(g, handle);
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
skynet_command(context, "EXIT", NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
skynet_error(context, "Invalid command %s",msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
sz |= type << HANDLE_REMOTE_SHIFT;
|
|
||||||
struct skynet_multicast_message * mc = skynet_multicast_create(msg, sz, source);
|
|
||||||
skynet_multicast_castgroup(context, g, mc);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
multicast_init(struct skynet_multicast_group *g, struct skynet_context *ctx, const char * args) {
|
|
||||||
skynet_callback(ctx, g, _maincb);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#include "skynet.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
_cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
|
|
||||||
uint32_t dest = (uint32_t)(uintptr_t)ud;
|
|
||||||
skynet_forward(context, dest);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tunnel_init(void * dummy, struct skynet_context *ctx, const char * args) {
|
|
||||||
uint32_t dest = skynet_queryname(ctx, args);
|
|
||||||
if (dest == 0) {
|
|
||||||
skynet_error(ctx, "Can't create tunnel to %s",args);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
skynet_callback(ctx, (void*)(intptr_t)dest, _cb);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -105,11 +105,9 @@ function COMMAND.help()
|
|||||||
list = "List all the service",
|
list = "List all the service",
|
||||||
stat = "Dump all stats",
|
stat = "Dump all stats",
|
||||||
info = "Info address : get service infomation",
|
info = "Info address : get service infomation",
|
||||||
timing = "timing address : get service timing infomation",
|
|
||||||
kill = "kill address : kill service",
|
kill = "kill address : kill service",
|
||||||
mem = "mem : show memory status",
|
mem = "mem : show memory status",
|
||||||
gc = "gc : force every lua service do garbage collect",
|
gc = "gc : force every lua service do garbage collect",
|
||||||
reload = "reload address : reload a lua service",
|
|
||||||
start = "lanuch a new lua service",
|
start = "lanuch a new lua service",
|
||||||
clearcache = "clear lua code cache",
|
clearcache = "clear lua code cache",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
local group_mgr = ...
|
|
||||||
|
|
||||||
group_mgr = tonumber(group_mgr)
|
|
||||||
|
|
||||||
local command = {}
|
|
||||||
local group = {}
|
|
||||||
|
|
||||||
function command.CREATE(id)
|
|
||||||
assert(group[id] == nil)
|
|
||||||
group[id] = {}
|
|
||||||
local recv_id = id * 2
|
|
||||||
local addr = skynet.query_group(recv_id)
|
|
||||||
skynet.ret(skynet.pack(addr))
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.AGENT(id, handle)
|
|
||||||
local tunnel = skynet.launch("tunnel", skynet.address(handle))
|
|
||||||
assert(tunnel)
|
|
||||||
local send_id = id * 2 + 1
|
|
||||||
skynet.enter_group(send_id, tunnel)
|
|
||||||
table.insert(group[id] , tunnel)
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.ENTER(id, handle)
|
|
||||||
local recv_id = id * 2
|
|
||||||
local send_id = id * 2 + 1
|
|
||||||
skynet.enter_group(recv_id, handle)
|
|
||||||
skynet.enter_group(send_id, handle)
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.LEAVE(id, handle)
|
|
||||||
local recv_id = id * 2
|
|
||||||
local send_id = id * 2 + 1
|
|
||||||
skynet.leave_group(recv_id, handle)
|
|
||||||
skynet.leave_group(send_id, handle)
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.CLEAR(id)
|
|
||||||
local g = group[id]
|
|
||||||
assert(g)
|
|
||||||
local recv_id = id * 2
|
|
||||||
local send_id = id * 2 + 1
|
|
||||||
skynet.clear_group(recv_id)
|
|
||||||
skynet.clear_group(send_id)
|
|
||||||
group[id] = nil
|
|
||||||
for _,v in ipairs(g) do
|
|
||||||
skynet.kill(v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
skynet.dispatch("lua", function(session, address, cmd , id , handle)
|
|
||||||
local f = command[cmd]
|
|
||||||
assert(f, cmd)
|
|
||||||
f(id,handle)
|
|
||||||
end)
|
|
||||||
skynet.send(group_mgr , "lua", "MASTER", skynet.self())
|
|
||||||
end)
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
local local_group = {}
|
|
||||||
for i=1,10000 do
|
|
||||||
local_group[i] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local command = {}
|
|
||||||
|
|
||||||
function command.NEW()
|
|
||||||
local k = next(local_group)
|
|
||||||
if k then
|
|
||||||
local_group[k] = nil
|
|
||||||
skynet.ret(skynet.pack(k))
|
|
||||||
else
|
|
||||||
skynet.ret(skynet.pack(nil))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.DELETE(id)
|
|
||||||
assert(handle_group[id] == nil)
|
|
||||||
skynet.clear_group(id)
|
|
||||||
local_group[id] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
skynet.dispatch("lua", function(_, _, cmd, id)
|
|
||||||
local f = command[cmd]
|
|
||||||
assert(f, cmd, id)
|
|
||||||
f(id)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
-- read group_local for id 10000
|
|
||||||
local id = 10000
|
|
||||||
local harbor_ctrl = {}
|
|
||||||
local multicast = {}
|
|
||||||
local command = {}
|
|
||||||
|
|
||||||
function command.MASTER(address, harbor)
|
|
||||||
harbor_ctrl[harbor] = address
|
|
||||||
end
|
|
||||||
|
|
||||||
local function create_group_in(harbor, id)
|
|
||||||
local local_ctrl = assert(harbor_ctrl[harbor])
|
|
||||||
local g = multicast[id]
|
|
||||||
g[harbor] = false
|
|
||||||
local local_mc = skynet.call(local_ctrl, "lua", "CREATE", id)
|
|
||||||
for _,mc in pairs(g) do
|
|
||||||
if mc then
|
|
||||||
skynet.send(local_ctrl, "lua", "AGENT", id, mc)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for harbor_id,ctrl in pairs(harbor_ctrl) do
|
|
||||||
if harbor_id ~= harbor then
|
|
||||||
skynet.send(ctrl, "lua", "AGENT", id, local_mc)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
g[harbor] = local_mc
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.NEW()
|
|
||||||
id = id + 1
|
|
||||||
multicast[id] = {}
|
|
||||||
skynet.ret(skynet.pack(id))
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.ENTER(address, harbor, id)
|
|
||||||
local g = multicast[id]
|
|
||||||
assert(g,id)
|
|
||||||
if g[harbor] == nil then
|
|
||||||
create_group_in(harbor, id)
|
|
||||||
end
|
|
||||||
local local_ctrl = assert(harbor_ctrl[harbor])
|
|
||||||
|
|
||||||
skynet.send(local_ctrl, "lua", "ENTER", id, address)
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.LEAVE(address, harbor, id)
|
|
||||||
assert(multicast[id], id)
|
|
||||||
local local_ctrl = assert(harbor_ctrl[harbor])
|
|
||||||
skynet.send(local_ctrl, "lua", "LEAVE", id, address)
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.DELETE(_,_, id)
|
|
||||||
assert(multicast[id], id)
|
|
||||||
multicast[id] = nil
|
|
||||||
|
|
||||||
for harbor_id,_ in pairs(g) do
|
|
||||||
skynet.send(harbor_ctrl[harbor_id], "lua", "CLEAR", id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
skynet.dispatch("lua", function(_, _, cmd, address, param)
|
|
||||||
local f = command[cmd]
|
|
||||||
assert(f, cmd, param)
|
|
||||||
local harbor = skynet.harbor(address)
|
|
||||||
f(address, harbor, param)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#define PTYPE_TEXT 0
|
#define PTYPE_TEXT 0
|
||||||
#define PTYPE_RESPONSE 1
|
#define PTYPE_RESPONSE 1
|
||||||
#define PTYPE_MULTICAST 2
|
#define PTYPE_MULTICAST_DEPRECATED 2
|
||||||
#define PTYPE_CLIENT 3
|
#define PTYPE_CLIENT 3
|
||||||
#define PTYPE_SYSTEM 4
|
#define PTYPE_SYSTEM 4
|
||||||
#define PTYPE_HARBOR 5
|
#define PTYPE_HARBOR 5
|
||||||
@@ -29,7 +29,6 @@ uint32_t skynet_queryname(struct skynet_context * context, const char * name);
|
|||||||
int skynet_send(struct skynet_context * context, uint32_t source, uint32_t destination , int type, int session, void * msg, size_t sz);
|
int skynet_send(struct skynet_context * context, uint32_t source, uint32_t destination , int type, int session, void * msg, size_t sz);
|
||||||
int skynet_sendname(struct skynet_context * context, const char * destination , int type, int session, void * msg, size_t sz);
|
int skynet_sendname(struct skynet_context * context, const char * destination , int type, int session, void * msg, size_t sz);
|
||||||
|
|
||||||
void skynet_forward(struct skynet_context *, uint32_t destination);
|
|
||||||
int skynet_isremote(struct skynet_context *, uint32_t handle, int * harbor);
|
int skynet_isremote(struct skynet_context *, uint32_t handle, int * harbor);
|
||||||
|
|
||||||
typedef int (*skynet_cb)(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz);
|
typedef int (*skynet_cb)(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz);
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
#include "skynet_group.h"
|
|
||||||
#include "skynet_multicast.h"
|
|
||||||
#include "skynet_server.h"
|
|
||||||
#include "skynet.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#define HASH_SIZE 1024
|
|
||||||
|
|
||||||
struct group_node {
|
|
||||||
int handle;
|
|
||||||
struct skynet_context *ctx;
|
|
||||||
struct group_node * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct group {
|
|
||||||
int lock;
|
|
||||||
struct group_node * node[HASH_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct group * _G = NULL;
|
|
||||||
|
|
||||||
inline static void
|
|
||||||
_lock(struct group *g) {
|
|
||||||
while (__sync_lock_test_and_set(&g->lock,1)) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void
|
|
||||||
_unlock(struct group *g) {
|
|
||||||
__sync_lock_release(&g->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct skynet_context *
|
|
||||||
_create_group(struct group * g, int handle) {
|
|
||||||
int hash = handle % HASH_SIZE;
|
|
||||||
struct skynet_context * inst = skynet_context_new("multicast",NULL);
|
|
||||||
assert(inst);
|
|
||||||
struct group_node * new_node = malloc(sizeof(struct group_node));
|
|
||||||
new_node->handle = handle;
|
|
||||||
new_node->ctx = inst;
|
|
||||||
new_node->next = g->node[hash];
|
|
||||||
g->node[hash] = new_node;
|
|
||||||
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
skynet_group_query(int handle) {
|
|
||||||
struct group *g = _G;
|
|
||||||
_lock(g);
|
|
||||||
|
|
||||||
int hash = handle % HASH_SIZE;
|
|
||||||
struct group_node * node = g->node[hash];
|
|
||||||
while (node) {
|
|
||||||
if (node->handle == handle) {
|
|
||||||
struct skynet_context * ctx = node->ctx;
|
|
||||||
uint32_t addr = skynet_context_handle(ctx);
|
|
||||||
_unlock(g);
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
struct skynet_context * ctx = _create_group(g, handle);
|
|
||||||
uint32_t addr = skynet_context_handle(ctx);
|
|
||||||
_unlock(g);
|
|
||||||
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_command(struct skynet_context *ctx, const char * cmd, uint32_t node) {
|
|
||||||
char * tmp = malloc(16);
|
|
||||||
int n = sprintf(tmp, "%s %x", cmd, node);
|
|
||||||
skynet_context_send(ctx, tmp, n+1 , 0, PTYPE_SYSTEM, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_group_enter(int handle, uint32_t n) {
|
|
||||||
struct group *g = _G;
|
|
||||||
_lock(g);
|
|
||||||
|
|
||||||
int hash = handle % HASH_SIZE;
|
|
||||||
struct group_node * node = g->node[hash];
|
|
||||||
while (node) {
|
|
||||||
if (node->handle == handle) {
|
|
||||||
send_command(node->ctx, "E", n);
|
|
||||||
_unlock(g);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
struct skynet_context * inst = _create_group(g, handle);
|
|
||||||
|
|
||||||
send_command(inst, "E", n);
|
|
||||||
|
|
||||||
_unlock(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_group_leave(int handle, uint32_t n) {
|
|
||||||
struct group *g = _G;
|
|
||||||
_lock(g);
|
|
||||||
|
|
||||||
int hash = handle % HASH_SIZE;
|
|
||||||
struct group_node * node = g->node[hash];
|
|
||||||
while (node) {
|
|
||||||
if (node->handle == handle) {
|
|
||||||
send_command(node->ctx, "L", n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
_unlock(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_group_clear(int handle) {
|
|
||||||
struct group *g = _G;
|
|
||||||
_lock(g);
|
|
||||||
|
|
||||||
int hash = handle % HASH_SIZE;
|
|
||||||
struct group_node ** pnode = &g->node[hash];
|
|
||||||
while (*pnode) {
|
|
||||||
struct group_node * node = *pnode;
|
|
||||||
if (node->handle == handle) {
|
|
||||||
struct skynet_context * ctx = node->ctx;
|
|
||||||
|
|
||||||
char * cmd = malloc(8);
|
|
||||||
int n = sprintf(cmd, "C");
|
|
||||||
skynet_context_send(ctx, cmd, n+1, 0 , PTYPE_SYSTEM, 0);
|
|
||||||
*pnode = node->next;
|
|
||||||
free(node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pnode = &node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
_unlock(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_group_init() {
|
|
||||||
struct group * g = malloc(sizeof(*g));
|
|
||||||
memset(g,0,sizeof(*g));
|
|
||||||
_G = g;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#ifndef SKYNET_GROUP_H
|
|
||||||
#define SKYNET_GROUP_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
uint32_t skynet_group_query(int handle);
|
|
||||||
void skynet_group_enter(int handle, uint32_t node);
|
|
||||||
void skynet_group_leave(int handle, uint32_t node);
|
|
||||||
void skynet_group_clear(int handle);
|
|
||||||
|
|
||||||
void skynet_group_init();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "skynet.h"
|
#include "skynet.h"
|
||||||
#include "skynet_mq.h"
|
#include "skynet_mq.h"
|
||||||
#include "skynet_handle.h"
|
#include "skynet_handle.h"
|
||||||
#include "skynet_multicast.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -287,13 +286,7 @@ _drop_queue(struct message_queue *q) {
|
|||||||
int s = 0;
|
int s = 0;
|
||||||
while(!skynet_mq_pop(q, &msg)) {
|
while(!skynet_mq_pop(q, &msg)) {
|
||||||
++s;
|
++s;
|
||||||
int type = msg.sz >> HANDLE_REMOTE_SHIFT;
|
free(msg.data);
|
||||||
if (type == PTYPE_MULTICAST) {
|
|
||||||
assert((msg.sz & HANDLE_MASK) == 0);
|
|
||||||
skynet_multicast_dispatch((struct skynet_multicast_message *)msg.data, NULL, NULL);
|
|
||||||
} else {
|
|
||||||
free(msg.data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_release(q);
|
_release(q);
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
#include "skynet.h"
|
|
||||||
#include "skynet_multicast.h"
|
|
||||||
#include "skynet_server.h"
|
|
||||||
#include "skynet_handle.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct skynet_multicast_message {
|
|
||||||
int ref;
|
|
||||||
const void * msg;
|
|
||||||
size_t sz;
|
|
||||||
uint32_t source;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skynet_multicast_message *
|
|
||||||
skynet_multicast_create(const void * msg, size_t sz, uint32_t source) {
|
|
||||||
struct skynet_multicast_message * mc = malloc(sizeof(*mc));
|
|
||||||
mc->ref = 0;
|
|
||||||
mc->msg = msg;
|
|
||||||
mc->sz = sz;
|
|
||||||
mc->source = source;
|
|
||||||
return mc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_multicast_copy(struct skynet_multicast_message *mc, int copy) {
|
|
||||||
int r = __sync_add_and_fetch(&mc->ref, copy);
|
|
||||||
if (r == 0) {
|
|
||||||
free((void *)mc->msg);
|
|
||||||
free(mc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_multicast_dispatch(struct skynet_multicast_message * msg, void * ud, skynet_multicast_func func) {
|
|
||||||
if (func) {
|
|
||||||
func(ud, msg->source, msg->msg, msg->sz);
|
|
||||||
}
|
|
||||||
int ref = __sync_sub_and_fetch(&msg->ref, 1);
|
|
||||||
if (ref == 0) {
|
|
||||||
free((void *)msg->msg);
|
|
||||||
free(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct array {
|
|
||||||
int cap;
|
|
||||||
int number;
|
|
||||||
uint32_t *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skynet_multicast_group {
|
|
||||||
struct array enter_queue;
|
|
||||||
struct array leave_queue;
|
|
||||||
int cap;
|
|
||||||
int number;
|
|
||||||
uint32_t * data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skynet_multicast_group *
|
|
||||||
skynet_multicast_newgroup() {
|
|
||||||
struct skynet_multicast_group * g = malloc(sizeof(*g));
|
|
||||||
memset(g,0,sizeof(*g));
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_multicast_deletegroup(struct skynet_multicast_group * g) {
|
|
||||||
free(g->data);
|
|
||||||
free(g->enter_queue.data);
|
|
||||||
free(g->leave_queue.data);
|
|
||||||
free(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
push_array(struct array * a, uint32_t v) {
|
|
||||||
if (a->number >= a->cap) {
|
|
||||||
a->cap *= 2;
|
|
||||||
if (a->cap == 0) {
|
|
||||||
a->cap = 4;
|
|
||||||
}
|
|
||||||
a->data = realloc(a->data, a->cap * sizeof(uint32_t));
|
|
||||||
}
|
|
||||||
a->data[a->number++] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_multicast_entergroup(struct skynet_multicast_group * group, uint32_t handle) {
|
|
||||||
push_array(&group->enter_queue, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_multicast_leavegroup(struct skynet_multicast_group * group, uint32_t handle) {
|
|
||||||
push_array(&group->leave_queue, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
compar_uint(const void *a, const void *b) {
|
|
||||||
const uint32_t * aa = a;
|
|
||||||
const uint32_t * bb = b;
|
|
||||||
return (int)(*aa - *bb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
combine_queue(struct skynet_context * from, struct skynet_multicast_group * group) {
|
|
||||||
qsort(group->enter_queue.data, group->enter_queue.number, sizeof(uint32_t), compar_uint);
|
|
||||||
qsort(group->leave_queue.data, group->leave_queue.number, sizeof(uint32_t), compar_uint);
|
|
||||||
int i;
|
|
||||||
int enter = group->enter_queue.number;
|
|
||||||
uint32_t last = 0;
|
|
||||||
|
|
||||||
int new_size = group->number + enter;
|
|
||||||
if (new_size > group->cap) {
|
|
||||||
group->data = realloc(group->data, new_size * sizeof(uint32_t));
|
|
||||||
group->cap = new_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// combine enter queue
|
|
||||||
int old_index = group->number - 1;
|
|
||||||
int new_index = new_size - 1;
|
|
||||||
for (i= enter - 1;i >=0 ; i--) {
|
|
||||||
uint32_t handle = group->enter_queue.data[i];
|
|
||||||
if (handle == last)
|
|
||||||
continue;
|
|
||||||
last = handle;
|
|
||||||
if (old_index < 0) {
|
|
||||||
group->data[new_index] = handle;
|
|
||||||
} else {
|
|
||||||
uint32_t p = group->data[old_index];
|
|
||||||
if (handle == p)
|
|
||||||
continue;
|
|
||||||
if (handle > p) {
|
|
||||||
group->data[new_index] = handle;
|
|
||||||
} else {
|
|
||||||
group->data[new_index] = group->data[old_index];
|
|
||||||
--old_index;
|
|
||||||
last = 0;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--new_index;
|
|
||||||
}
|
|
||||||
while (old_index >= 0) {
|
|
||||||
group->data[new_index] = group->data[old_index];
|
|
||||||
--old_index;
|
|
||||||
--new_index;
|
|
||||||
}
|
|
||||||
group->enter_queue.number = 0;
|
|
||||||
|
|
||||||
// remove leave queue
|
|
||||||
old_index = new_index + 1;
|
|
||||||
new_index = 0;
|
|
||||||
|
|
||||||
int count = new_size - old_index;
|
|
||||||
|
|
||||||
int leave = group->leave_queue.number;
|
|
||||||
for (i=0;i<leave;i++) {
|
|
||||||
if (old_index >= new_size) {
|
|
||||||
count = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
uint32_t handle = group->leave_queue.data[i];
|
|
||||||
uint32_t p = group->data[old_index];
|
|
||||||
if (handle == p) {
|
|
||||||
--count;
|
|
||||||
++old_index;
|
|
||||||
} else if ( handle > p) {
|
|
||||||
group->data[new_index] = group->data[old_index];
|
|
||||||
++new_index;
|
|
||||||
++old_index;
|
|
||||||
--i;
|
|
||||||
} else {
|
|
||||||
skynet_error(from, "Try to remove a none exist handle : %x", handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (new_index < count) {
|
|
||||||
group->data[new_index] = group->data[old_index];
|
|
||||||
++new_index;
|
|
||||||
++old_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
group->leave_queue.number = 0;
|
|
||||||
|
|
||||||
group->number = new_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
skynet_multicast_castgroup(struct skynet_context * from, struct skynet_multicast_group * group, struct skynet_multicast_message *msg) {
|
|
||||||
combine_queue(from, group);
|
|
||||||
int release = 0;
|
|
||||||
if (group->number > 0) {
|
|
||||||
uint32_t source = skynet_context_handle(from);
|
|
||||||
skynet_multicast_copy(msg, group->number);
|
|
||||||
int i;
|
|
||||||
for (i=0;i<group->number;i++) {
|
|
||||||
uint32_t p = group->data[i];
|
|
||||||
struct skynet_context * ctx = skynet_handle_grab(p);
|
|
||||||
if (ctx) {
|
|
||||||
skynet_context_send(ctx, msg, 0 , source, PTYPE_MULTICAST , 0);
|
|
||||||
skynet_context_release(ctx);
|
|
||||||
} else {
|
|
||||||
skynet_multicast_leavegroup(group, p);
|
|
||||||
++release;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
skynet_multicast_copy(msg, -release);
|
|
||||||
|
|
||||||
return group->number - release;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skynet_multicast_cast(struct skynet_context * from, struct skynet_multicast_message *msg, const uint32_t *dests, int n) {
|
|
||||||
uint32_t source = skynet_context_handle(from);
|
|
||||||
skynet_multicast_copy(msg, n);
|
|
||||||
if (n == 0)
|
|
||||||
return;
|
|
||||||
int i;
|
|
||||||
int release = 0;
|
|
||||||
for (i=0;i<n;i++) {
|
|
||||||
uint32_t p = dests[i];
|
|
||||||
struct skynet_context * ctx = skynet_handle_grab(p);
|
|
||||||
if (ctx) {
|
|
||||||
skynet_context_send(ctx, msg, 0 , source, PTYPE_MULTICAST , 0);
|
|
||||||
skynet_context_release(ctx);
|
|
||||||
} else {
|
|
||||||
++release;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (release != 0) {
|
|
||||||
skynet_multicast_copy(msg, -release);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#ifndef SKYNET_MULTICAST_H
|
|
||||||
#define SKYNET_MULTICAST_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct skynet_multicast_message;
|
|
||||||
struct skynet_multicast_group;
|
|
||||||
struct skynet_context;
|
|
||||||
|
|
||||||
typedef void (*skynet_multicast_func)(void *ud, uint32_t source, const void * msg, size_t sz);
|
|
||||||
|
|
||||||
struct skynet_multicast_message * skynet_multicast_create(const void * msg, size_t sz, uint32_t source);
|
|
||||||
void skynet_multicast_copy(struct skynet_multicast_message *, int copy);
|
|
||||||
void skynet_multicast_dispatch(struct skynet_multicast_message * msg, void * ud, skynet_multicast_func func);
|
|
||||||
void skynet_multicast_cast(struct skynet_context * from, struct skynet_multicast_message *msg, const uint32_t *dests, int n);
|
|
||||||
|
|
||||||
struct skynet_multicast_group * skynet_multicast_newgroup();
|
|
||||||
void skynet_multicast_deletegroup(struct skynet_multicast_group * group);
|
|
||||||
void skynet_multicast_entergroup(struct skynet_multicast_group * group, uint32_t handle);
|
|
||||||
void skynet_multicast_leavegroup(struct skynet_multicast_group * group, uint32_t handle);
|
|
||||||
int skynet_multicast_castgroup(struct skynet_context * from, struct skynet_multicast_group * group, struct skynet_multicast_message *msg);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -6,8 +6,6 @@
|
|||||||
#include "skynet_harbor.h"
|
#include "skynet_harbor.h"
|
||||||
#include "skynet_env.h"
|
#include "skynet_env.h"
|
||||||
#include "skynet.h"
|
#include "skynet.h"
|
||||||
#include "skynet_multicast.h"
|
|
||||||
#include "skynet_group.h"
|
|
||||||
#include "skynet_monitor.h"
|
#include "skynet_monitor.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -41,7 +39,6 @@ struct skynet_context {
|
|||||||
void * cb_ud;
|
void * cb_ud;
|
||||||
skynet_cb cb;
|
skynet_cb cb;
|
||||||
int session_id;
|
int session_id;
|
||||||
uint32_t forward;
|
|
||||||
struct message_queue *queue;
|
struct message_queue *queue;
|
||||||
bool init;
|
bool init;
|
||||||
bool endless;
|
bool endless;
|
||||||
@@ -102,7 +99,6 @@ skynet_context_new(const char * name, const char *param) {
|
|||||||
ctx->cb_ud = NULL;
|
ctx->cb_ud = NULL;
|
||||||
ctx->session_id = 0;
|
ctx->session_id = 0;
|
||||||
|
|
||||||
ctx->forward = 0;
|
|
||||||
ctx->init = false;
|
ctx->init = false;
|
||||||
ctx->endless = false;
|
ctx->endless = false;
|
||||||
ctx->handle = skynet_handle_register(ctx);
|
ctx->handle = skynet_handle_register(ctx);
|
||||||
@@ -192,66 +188,14 @@ skynet_isremote(struct skynet_context * ctx, uint32_t handle, int * harbor) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_send_message(uint32_t des, struct skynet_message *msg) {
|
|
||||||
if (skynet_harbor_message_isremote(des)) {
|
|
||||||
struct remote_message * rmsg = malloc(sizeof(*rmsg));
|
|
||||||
rmsg->destination.handle = des;
|
|
||||||
rmsg->message = msg->data;
|
|
||||||
rmsg->sz = msg->sz;
|
|
||||||
skynet_harbor_send(rmsg, msg->source, msg->session);
|
|
||||||
} else {
|
|
||||||
if (skynet_context_push(des, msg)) {
|
|
||||||
free(msg->data);
|
|
||||||
skynet_error(NULL, "Drop message from %x forward to %x (size=%d)", msg->source, des, (int)msg->sz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_forwarding(struct skynet_context *ctx, struct skynet_message *msg) {
|
|
||||||
if (ctx->forward) {
|
|
||||||
uint32_t des = ctx->forward;
|
|
||||||
ctx->forward = 0;
|
|
||||||
_send_message(des, msg);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_mc(void *ud, uint32_t source, const void * msg, size_t sz) {
|
|
||||||
struct skynet_context * ctx = ud;
|
|
||||||
int type = sz >> HANDLE_REMOTE_SHIFT;
|
|
||||||
sz &= HANDLE_MASK;
|
|
||||||
ctx->cb(ctx, ctx->cb_ud, type, 0, source, msg, sz);
|
|
||||||
if (ctx->forward) {
|
|
||||||
uint32_t des = ctx->forward;
|
|
||||||
ctx->forward = 0;
|
|
||||||
struct skynet_message message;
|
|
||||||
message.source = source;
|
|
||||||
message.session = 0;
|
|
||||||
message.data = malloc(sz);
|
|
||||||
memcpy(message.data, msg, sz);
|
|
||||||
message.sz = sz | (type << HANDLE_REMOTE_SHIFT);
|
|
||||||
_send_message(des, &message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_dispatch_message(struct skynet_context *ctx, struct skynet_message *msg) {
|
_dispatch_message(struct skynet_context *ctx, struct skynet_message *msg) {
|
||||||
assert(ctx->init);
|
assert(ctx->init);
|
||||||
CHECKCALLING_BEGIN(ctx)
|
CHECKCALLING_BEGIN(ctx)
|
||||||
int type = msg->sz >> HANDLE_REMOTE_SHIFT;
|
int type = msg->sz >> HANDLE_REMOTE_SHIFT;
|
||||||
size_t sz = msg->sz & HANDLE_MASK;
|
size_t sz = msg->sz & HANDLE_MASK;
|
||||||
if (type == PTYPE_MULTICAST) {
|
if (!ctx->cb(ctx, ctx->cb_ud, type, msg->session, msg->source, msg->data, sz)) {
|
||||||
skynet_multicast_dispatch((struct skynet_multicast_message *)msg->data, ctx, _mc);
|
free(msg->data);
|
||||||
} else {
|
|
||||||
int reserve = ctx->cb(ctx, ctx->cb_ud, type, msg->session, msg->source, msg->data, sz);
|
|
||||||
reserve |= _forwarding(ctx, msg);
|
|
||||||
if (!reserve) {
|
|
||||||
free(msg->data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CHECKCALLING_END(ctx)
|
CHECKCALLING_END(ctx)
|
||||||
}
|
}
|
||||||
@@ -308,41 +252,6 @@ _copy_name(char name[GLOBALNAME_LENGTH], const char * addr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
|
||||||
_group_command(struct skynet_context * ctx, const char * cmd, int handle, uint32_t v) {
|
|
||||||
uint32_t self;
|
|
||||||
if (v != 0) {
|
|
||||||
if (skynet_harbor_message_isremote(v)) {
|
|
||||||
skynet_error(ctx, "Can't add remote handle %x",v);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
self = v;
|
|
||||||
} else {
|
|
||||||
self = ctx->handle;
|
|
||||||
}
|
|
||||||
if (strcmp(cmd, "ENTER") == 0) {
|
|
||||||
skynet_group_enter(handle, self);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (strcmp(cmd, "LEAVE") == 0) {
|
|
||||||
skynet_group_leave(handle, self);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (strcmp(cmd, "QUERY") == 0) {
|
|
||||||
uint32_t addr = skynet_group_query(handle);
|
|
||||||
if (addr == 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
_id_to_hex(ctx->result, addr);
|
|
||||||
return ctx->result;
|
|
||||||
}
|
|
||||||
if (strcmp(cmd, "CLEAR") == 0) {
|
|
||||||
skynet_group_clear(handle);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
skynet_queryname(struct skynet_context * context, const char * name) {
|
skynet_queryname(struct skynet_context * context, const char * name) {
|
||||||
switch(name[0]) {
|
switch(name[0]) {
|
||||||
@@ -514,18 +423,6 @@ skynet_command(struct skynet_context * context, const char * cmd , const char *
|
|||||||
return context->result;
|
return context->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(cmd,"GROUP") == 0) {
|
|
||||||
int sz = strlen(param);
|
|
||||||
char tmp[sz+1];
|
|
||||||
strcpy(tmp,param);
|
|
||||||
tmp[sz] = '\0';
|
|
||||||
char cmd[sz+1];
|
|
||||||
int handle=0;
|
|
||||||
uint32_t addr=0;
|
|
||||||
sscanf(tmp, "%s %d :%x",cmd,&handle,&addr);
|
|
||||||
return _group_command(context, cmd, handle,addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(cmd,"ENDLESS") == 0) {
|
if (strcmp(cmd,"ENDLESS") == 0) {
|
||||||
if (context->endless) {
|
if (context->endless) {
|
||||||
strcpy(context->result, "1");
|
strcpy(context->result, "1");
|
||||||
@@ -572,16 +469,6 @@ skynet_command(struct skynet_context * context, const char * cmd , const char *
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
skynet_forward(struct skynet_context * context, uint32_t destination) {
|
|
||||||
assert(context->forward == 0);
|
|
||||||
if (destination == 0) {
|
|
||||||
context->forward = context->handle;
|
|
||||||
} else {
|
|
||||||
context->forward = destination;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_filter_args(struct skynet_context * context, int type, int *session, void ** data, size_t * sz) {
|
_filter_args(struct skynet_context * context, int type, int *session, void ** data, size_t * sz) {
|
||||||
int needcopy = !(type & PTYPE_TAG_DONTCOPY);
|
int needcopy = !(type & PTYPE_TAG_DONTCOPY);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "skynet_module.h"
|
#include "skynet_module.h"
|
||||||
#include "skynet_timer.h"
|
#include "skynet_timer.h"
|
||||||
#include "skynet_harbor.h"
|
#include "skynet_harbor.h"
|
||||||
#include "skynet_group.h"
|
|
||||||
#include "skynet_monitor.h"
|
#include "skynet_monitor.h"
|
||||||
#include "skynet_socket.h"
|
#include "skynet_socket.h"
|
||||||
|
|
||||||
@@ -188,7 +187,6 @@ _start_master(const char * master) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
skynet_start(struct skynet_config * config) {
|
skynet_start(struct skynet_config * config) {
|
||||||
skynet_group_init();
|
|
||||||
skynet_harbor_init(config->harbor);
|
skynet_harbor_init(config->harbor);
|
||||||
skynet_handle_init(config->harbor);
|
skynet_handle_init(config->harbor);
|
||||||
skynet_mq_init();
|
skynet_mq_init();
|
||||||
@@ -215,11 +213,6 @@ skynet_start(struct skynet_config * config) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = skynet_context_new("localcast", NULL);
|
|
||||||
if (ctx == NULL) {
|
|
||||||
fprintf(stderr,"launch local cast error");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
ctx = skynet_context_new("snlua", "launcher");
|
ctx = skynet_context_new("snlua", "launcher");
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
skynet_command(ctx, "REG", ".launcher");
|
skynet_command(ctx, "REG", ".launcher");
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
local result = skynet.call("SIMPLEDB","text","SET","foobar","hello")
|
|
||||||
print(result)
|
|
||||||
result = skynet.call("SIMPLEDB","text","GET","foobar")
|
|
||||||
print(result)
|
|
||||||
skynet.exit()
|
|
||||||
end)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
local group = require "mcgroup"
|
|
||||||
--local group = require "localgroup"
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
local gid = group.create()
|
|
||||||
local gaddr = group.address(gid)
|
|
||||||
local g = {}
|
|
||||||
print("=== Create Group ===",gid,skynet.address(gaddr))
|
|
||||||
for i=1,10 do
|
|
||||||
local address = skynet.newservice("testgroup_c", tostring(i))
|
|
||||||
table.insert(g, address)
|
|
||||||
group.enter(gid , address)
|
|
||||||
end
|
|
||||||
skynet.cast(g,"text","Cast")
|
|
||||||
skynet.sleep(1000)
|
|
||||||
skynet.send(gaddr,"text","Hello World")
|
|
||||||
skynet.exit()
|
|
||||||
end)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
local group = require "mcgroup"
|
|
||||||
--local group = require "localgroup"
|
|
||||||
local id, g = ...
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
skynet.dispatch("text",function(session,address,text)
|
|
||||||
print("===>",id, text)
|
|
||||||
end)
|
|
||||||
if g then
|
|
||||||
group.enter(tonumber(g))
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
local mqueue = require "mqueue"
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
local pingqueue = skynet.newservice "pingqueue"
|
|
||||||
print(mqueue.call(pingqueue, "A"))
|
|
||||||
print(mqueue.call(pingqueue, "B"))
|
|
||||||
print(mqueue.call(pingqueue, "C"))
|
|
||||||
skynet.exit()
|
|
||||||
end)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
local trace_cache = {}
|
|
||||||
|
|
||||||
skynet.trace_callback(function(handle, ti)
|
|
||||||
-- skynet will call this function when the thread which create handle(traceid) end, and pass the time (ti)
|
|
||||||
print("TRACE",trace_cache[handle],ti)
|
|
||||||
trace_cache[handle] = nil
|
|
||||||
end)
|
|
||||||
|
|
||||||
local function f (i)
|
|
||||||
-- create a trace object
|
|
||||||
local traceid = skynet.trace()
|
|
||||||
-- name traceid in trace_cache[]
|
|
||||||
trace_cache[traceid] = "thread " .. i
|
|
||||||
|
|
||||||
for i=1,i do
|
|
||||||
skynet.sleep(i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
for i = 1 , 100 do
|
|
||||||
skynet.fork(f, i)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user