mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
add module signal and hack lua to support it :)
This commit is contained in:
@@ -458,6 +458,11 @@ struct lua_Debug {
|
|||||||
|
|
||||||
/* }====================================================================== */
|
/* }====================================================================== */
|
||||||
|
|
||||||
|
/* Add by skynet */
|
||||||
|
|
||||||
|
extern lua_State * skynet_sig_L;
|
||||||
|
LUA_API void (lua_checksig_)(lua_State *L);
|
||||||
|
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
|
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
|
||||||
|
|||||||
@@ -43,6 +43,17 @@
|
|||||||
/* limit for table tag-method chains (to avoid loops) */
|
/* limit for table tag-method chains (to avoid loops) */
|
||||||
#define MAXTAGLOOP 2000
|
#define MAXTAGLOOP 2000
|
||||||
|
|
||||||
|
/* Add by skynet */
|
||||||
|
lua_State * skynet_sig_L = NULL;
|
||||||
|
|
||||||
|
LUA_API void
|
||||||
|
lua_checksig_(lua_State *L) {
|
||||||
|
if (skynet_sig_L == G(L)->mainthread) {
|
||||||
|
skynet_sig_L = NULL;
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_error(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Similar to 'tonumber', but does not attempt to convert strings and
|
** Similar to 'tonumber', but does not attempt to convert strings and
|
||||||
@@ -935,6 +946,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_JMP) {
|
vmcase(OP_JMP) {
|
||||||
|
lua_checksig(L);
|
||||||
dojump(ci, i, 0);
|
dojump(ci, i, 0);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
@@ -987,6 +999,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
vmcase(OP_CALL) {
|
vmcase(OP_CALL) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int nresults = GETARG_C(i) - 1;
|
int nresults = GETARG_C(i) - 1;
|
||||||
|
lua_checksig(L);
|
||||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||||
if (luaD_precall(L, ra, nresults)) { /* C function? */
|
if (luaD_precall(L, ra, nresults)) { /* C function? */
|
||||||
if (nresults >= 0) L->top = ci->top; /* adjust results */
|
if (nresults >= 0) L->top = ci->top; /* adjust results */
|
||||||
@@ -1001,6 +1014,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
}
|
}
|
||||||
vmcase(OP_TAILCALL) {
|
vmcase(OP_TAILCALL) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
|
lua_checksig(L);
|
||||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||||
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
||||||
if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */
|
if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */
|
||||||
@@ -1111,6 +1125,7 @@ void luaV_execute (lua_State *L) {
|
|||||||
}
|
}
|
||||||
vmcase(OP_TFORLOOP) {
|
vmcase(OP_TFORLOOP) {
|
||||||
l_tforloop:
|
l_tforloop:
|
||||||
|
lua_checksig(L);
|
||||||
if (!ttisnil(ra + 1)) { /* continue loop? */
|
if (!ttisnil(ra + 1)) { /* continue loop? */
|
||||||
setobjs2s(L, ra, ra + 1); /* save control variable */
|
setobjs2s(L, ra, ra + 1); /* save control variable */
|
||||||
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
||||||
|
|||||||
@@ -156,3 +156,9 @@ snlua_release(struct snlua *l) {
|
|||||||
lua_close(l->L);
|
lua_close(l->L);
|
||||||
skynet_free(l);
|
skynet_free(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
snlua_signal(struct snlua *l, int signal) {
|
||||||
|
skynet_error(l->ctx, "recv a signal %d", signal);
|
||||||
|
skynet_sig_L = l->L;
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,8 +50,11 @@ end
|
|||||||
|
|
||||||
local function docmd(cmdline, print, fd)
|
local function docmd(cmdline, print, fd)
|
||||||
local split = split_cmdline(cmdline)
|
local split = split_cmdline(cmdline)
|
||||||
table.insert(split, fd)
|
local command = split[1]
|
||||||
local cmd = COMMAND[split[1]]
|
if command == "debug" then
|
||||||
|
table.insert(split, fd)
|
||||||
|
end
|
||||||
|
local cmd = COMMAND[command]
|
||||||
local ok, list
|
local ok, list
|
||||||
if cmd then
|
if cmd then
|
||||||
ok, list = pcall(cmd, select(2,table.unpack(split)))
|
ok, list = pcall(cmd, select(2,table.unpack(split)))
|
||||||
@@ -126,6 +129,7 @@ function COMMAND.help()
|
|||||||
logoff = "logoff address",
|
logoff = "logoff address",
|
||||||
log = "launch a new lua service with log",
|
log = "launch a new lua service with log",
|
||||||
debug = "debug address : debug a lua service",
|
debug = "debug address : debug a lua service",
|
||||||
|
signal = "signal address sig",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -244,3 +248,12 @@ function COMMAND.logoff(address)
|
|||||||
address = adjust_address(address)
|
address = adjust_address(address)
|
||||||
core.command("LOGOFF", skynet.address(address))
|
core.command("LOGOFF", skynet.address(address))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function COMMAND.signal(address, sig)
|
||||||
|
address = skynet.address(adjust_address(address))
|
||||||
|
if sig then
|
||||||
|
core.command("SIGNAL", string.format("%s %d",address,sig))
|
||||||
|
else
|
||||||
|
core.command("SIGNAL", address)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ _query(const char * name) {
|
|||||||
static int
|
static int
|
||||||
_open_sym(struct skynet_module *mod) {
|
_open_sym(struct skynet_module *mod) {
|
||||||
size_t name_size = strlen(mod->name);
|
size_t name_size = strlen(mod->name);
|
||||||
char tmp[name_size + 9]; // create/init/release , longest name is release (7)
|
char tmp[name_size + 9]; // create/init/release/signal , longest name is release (7)
|
||||||
memcpy(tmp, mod->name, name_size);
|
memcpy(tmp, mod->name, name_size);
|
||||||
strcpy(tmp+name_size, "_create");
|
strcpy(tmp+name_size, "_create");
|
||||||
mod->create = dlsym(mod->module, tmp);
|
mod->create = dlsym(mod->module, tmp);
|
||||||
@@ -83,6 +83,8 @@ _open_sym(struct skynet_module *mod) {
|
|||||||
mod->init = dlsym(mod->module, tmp);
|
mod->init = dlsym(mod->module, tmp);
|
||||||
strcpy(tmp+name_size, "_release");
|
strcpy(tmp+name_size, "_release");
|
||||||
mod->release = dlsym(mod->module, tmp);
|
mod->release = dlsym(mod->module, tmp);
|
||||||
|
strcpy(tmp+name_size, "_signal");
|
||||||
|
mod->signal = dlsym(mod->module, tmp);
|
||||||
|
|
||||||
return mod->init == NULL;
|
return mod->init == NULL;
|
||||||
}
|
}
|
||||||
@@ -150,6 +152,13 @@ skynet_module_instance_release(struct skynet_module *m, void *inst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
skynet_module_instance_signal(struct skynet_module *m, void *inst, int signal) {
|
||||||
|
if (m->signal) {
|
||||||
|
m->signal(inst, signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
skynet_module_init(const char *path) {
|
skynet_module_init(const char *path) {
|
||||||
struct modules *m = skynet_malloc(sizeof(*m));
|
struct modules *m = skynet_malloc(sizeof(*m));
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ struct skynet_context;
|
|||||||
typedef void * (*skynet_dl_create)(void);
|
typedef void * (*skynet_dl_create)(void);
|
||||||
typedef int (*skynet_dl_init)(void * inst, struct skynet_context *, const char * parm);
|
typedef int (*skynet_dl_init)(void * inst, struct skynet_context *, const char * parm);
|
||||||
typedef void (*skynet_dl_release)(void * inst);
|
typedef void (*skynet_dl_release)(void * inst);
|
||||||
|
typedef void (*skynet_dl_signal)(void * inst, int signal);
|
||||||
|
|
||||||
struct skynet_module {
|
struct skynet_module {
|
||||||
const char * name;
|
const char * name;
|
||||||
@@ -13,6 +14,7 @@ struct skynet_module {
|
|||||||
skynet_dl_create create;
|
skynet_dl_create create;
|
||||||
skynet_dl_init init;
|
skynet_dl_init init;
|
||||||
skynet_dl_release release;
|
skynet_dl_release release;
|
||||||
|
skynet_dl_signal signal;
|
||||||
};
|
};
|
||||||
|
|
||||||
void skynet_module_insert(struct skynet_module *mod);
|
void skynet_module_insert(struct skynet_module *mod);
|
||||||
@@ -20,6 +22,7 @@ struct skynet_module * skynet_module_query(const char * name);
|
|||||||
void * skynet_module_instance_create(struct skynet_module *);
|
void * skynet_module_instance_create(struct skynet_module *);
|
||||||
int skynet_module_instance_init(struct skynet_module *, void * inst, struct skynet_context *ctx, const char * parm);
|
int skynet_module_instance_init(struct skynet_module *, void * inst, struct skynet_context *ctx, const char * parm);
|
||||||
void skynet_module_instance_release(struct skynet_module *, void *inst);
|
void skynet_module_instance_release(struct skynet_module *, void *inst);
|
||||||
|
void skynet_module_instance_signal(struct skynet_module *, void *inst, int signal);
|
||||||
|
|
||||||
void skynet_module_init(const char *path);
|
void skynet_module_init(const char *path);
|
||||||
|
|
||||||
|
|||||||
@@ -589,6 +589,26 @@ cmd_logoff(struct skynet_context * context, const char * param) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
cmd_signal(struct skynet_context * context, const char * param) {
|
||||||
|
uint32_t handle = tohandle(context, param);
|
||||||
|
if (handle == 0)
|
||||||
|
return NULL;
|
||||||
|
struct skynet_context * ctx = skynet_handle_grab(handle);
|
||||||
|
if (ctx == NULL)
|
||||||
|
return NULL;
|
||||||
|
param = strchr(param, ' ');
|
||||||
|
int sig = 0;
|
||||||
|
if (param) {
|
||||||
|
sig = strtol(param, NULL, 0);
|
||||||
|
}
|
||||||
|
// NOTICE: the signal function should be thread safe.
|
||||||
|
skynet_module_instance_signal(ctx->mod, ctx->instance, sig);
|
||||||
|
|
||||||
|
skynet_context_release(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct command_func cmd_funcs[] = {
|
static struct command_func cmd_funcs[] = {
|
||||||
{ "TIMEOUT", cmd_timeout },
|
{ "TIMEOUT", cmd_timeout },
|
||||||
{ "REG", cmd_reg },
|
{ "REG", cmd_reg },
|
||||||
@@ -607,6 +627,7 @@ static struct command_func cmd_funcs[] = {
|
|||||||
{ "MQLEN", cmd_mqlen },
|
{ "MQLEN", cmd_mqlen },
|
||||||
{ "LOGON", cmd_logon },
|
{ "LOGON", cmd_logon },
|
||||||
{ "LOGOFF", cmd_logoff },
|
{ "LOGOFF", cmd_logoff },
|
||||||
|
{ "SIGNAL", cmd_signal },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user