merge pr 103

This commit is contained in:
Cloud Wu
2014-05-12 11:04:58 +08:00
parent 8d8cb17e0a
commit 7dff50d21d

View File

@@ -64,12 +64,12 @@ skynet_context_total() {
}
static void
_context_inc() {
context_inc() {
__sync_fetch_and_add(&G_NODE.total,1);
}
static void
_context_dec() {
context_dec() {
__sync_fetch_and_sub(&G_NODE.total,1);
}
@@ -80,7 +80,7 @@ skynet_current_handle(void) {
}
static void
_id_to_hex(char * str, uint32_t id) {
id_to_hex(char * str, uint32_t id) {
int i;
static char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
str[0] = ':';
@@ -129,7 +129,7 @@ skynet_context_new(const char * name, const char *param) {
ctx->handle = skynet_handle_register(ctx);
struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
// init function maybe use ctx->handle, so it must init at last
_context_inc();
context_inc();
CHECKCALLING_BEGIN(ctx)
int r = skynet_module_instance_init(mod, inst, ctx, param);
@@ -168,17 +168,17 @@ skynet_context_grab(struct skynet_context *ctx) {
}
static void
_delete_context(struct skynet_context *ctx) {
delete_context(struct skynet_context *ctx) {
skynet_module_instance_release(ctx->mod, ctx->instance);
skynet_mq_mark_release(ctx->queue);
skynet_free(ctx);
_context_dec();
context_dec();
}
struct skynet_context *
skynet_context_release(struct skynet_context *ctx) {
if (__sync_sub_and_fetch(&ctx->ref,1) == 0) {
_delete_context(ctx);
delete_context(ctx);
return NULL;
}
return ctx;
@@ -267,7 +267,7 @@ skynet_context_message_dispatch(struct skynet_monitor *sm) {
}
static void
_copy_name(char name[GLOBALNAME_LENGTH], const char * addr) {
copy_name(char name[GLOBALNAME_LENGTH], const char * addr) {
int i;
for (i=0;i<GLOBALNAME_LENGTH && addr[i];i++) {
name[i] = addr[i];
@@ -303,176 +303,225 @@ handle_exit(struct skynet_context * context, uint32_t handle) {
skynet_handle_retire(handle);
}
const char *
skynet_command(struct skynet_context * context, const char * cmd , const char * param) {
if (strcmp(cmd,"TIMEOUT") == 0) {
char * session_ptr = NULL;
int ti = strtol(param, &session_ptr, 10);
int session = skynet_context_newsession(context);
skynet_timeout(context->handle, ti, session);
sprintf(context->result, "%d", session);
// skynet command
struct command_func {
const char *name;
const char * (*func)(struct skynet_context * context, const char * param);
};
static const char *
cmd_timeout(struct skynet_context * context, const char * param) {
char * session_ptr = NULL;
int ti = strtol(param, &session_ptr, 10);
int session = skynet_context_newsession(context);
skynet_timeout(context->handle, ti, session);
sprintf(context->result, "%d", session);
return context->result;
}
static const char *
cmd_reg(struct skynet_context * context, const char * param) {
if (param == NULL || param[0] == '\0') {
sprintf(context->result, ":%x", context->handle);
return context->result;
} else if (param[0] == '.') {
return skynet_handle_namehandle(context->handle, param + 1);
} else {
assert(context->handle!=0);
struct remote_name *rname = skynet_malloc(sizeof(*rname));
copy_name(rname->name, param);
rname->handle = context->handle;
skynet_harbor_register(rname);
return NULL;
}
}
static const char *
cmd_query(struct skynet_context * context, const char * param) {
if (param[0] == '.') {
uint32_t handle = skynet_handle_findname(param+1);
sprintf(context->result, ":%x", handle);
return context->result;
}
return NULL;
}
if (strcmp(cmd,"REG") == 0) {
if (param == NULL || param[0] == '\0') {
sprintf(context->result, ":%x", context->handle);
return context->result;
} else if (param[0] == '.') {
return skynet_handle_namehandle(context->handle, param + 1);
} else {
assert(context->handle!=0);
struct remote_name *rname = skynet_malloc(sizeof(*rname));
_copy_name(rname->name, param);
rname->handle = context->handle;
skynet_harbor_register(rname);
return NULL;
}
static const char *
cmd_name(struct skynet_context * context, const char * param) {
int size = strlen(param);
char name[size+1];
char handle[size+1];
sscanf(param,"%s %s",name,handle);
if (handle[0] != ':') {
return NULL;
}
uint32_t handle_id = strtoul(handle+1, NULL, 16);
if (handle_id == 0) {
return NULL;
}
if (name[0] == '.') {
return skynet_handle_namehandle(handle_id, name + 1);
} else {
struct remote_name *rname = skynet_malloc(sizeof(*rname));
copy_name(rname->name, name);
rname->handle = handle_id;
skynet_harbor_register(rname);
}
return NULL;
}
if (strcmp(cmd,"QUERY") == 0) {
if (param[0] == '.') {
uint32_t handle = skynet_handle_findname(param+1);
sprintf(context->result, ":%x", handle);
static const char *
cmd_now(struct skynet_context * context, const char * param) {
uint32_t ti = skynet_gettime();
sprintf(context->result,"%u",ti);
return context->result;
}
static const char *
cmd_exit(struct skynet_context * context, const char * param) {
handle_exit(context, 0);
return NULL;
}
static const char *
cmd_kill(struct skynet_context * context, const char * param) {
uint32_t handle = 0;
if (param[0] == ':') {
handle = strtoul(param+1, NULL, 16);
} else if (param[0] == '.') {
handle = skynet_handle_findname(param+1);
} else {
skynet_error(context, "Can't kill %s",param);
// todo : kill global service
}
if (handle) {
handle_exit(context, handle);
}
return NULL;
}
static const char *
cmd_launch(struct skynet_context * context, const char * param) {
size_t sz = strlen(param);
char tmp[sz+1];
strcpy(tmp,param);
char * args = tmp;
char * mod = strsep(&args, " \t\r\n");
args = strsep(&args, "\r\n");
struct skynet_context * inst = skynet_context_new(mod,args);
if (inst == NULL) {
return NULL;
} else {
id_to_hex(context->result, inst->handle);
return context->result;
}
}
static const char *
cmd_getenv(struct skynet_context * context, const char * param) {
return skynet_getenv(param);
}
static const char *
cmd_setenv(struct skynet_context * context, const char * param) {
size_t sz = strlen(param);
char key[sz+1];
int i;
for (i=0;param[i] != ' ' && param[i];i++) {
key[i] = param[i];
}
if (param[i] == '\0')
return NULL;
key[i] = '\0';
param += i+1;
skynet_setenv(key,param);
return NULL;
}
static const char *
cmd_starttime(struct skynet_context * context, const char * param) {
uint32_t sec = skynet_gettime_fixsec();
sprintf(context->result,"%u",sec);
return context->result;
}
static const char *
cmd_endless(struct skynet_context * context, const char * param) {
if (context->endless) {
strcpy(context->result, "1");
context->endless = false;
return context->result;
}
return NULL;
}
static const char *
cmd_abort(struct skynet_context * context, const char * param) {
skynet_handle_retireall();
return NULL;
}
static const char *
cmd_monitor(struct skynet_context * context, const char * param) {
uint32_t handle=0;
if (param == NULL || param[0] == '\0') {
if (G_NODE.monitor_exit) {
// return current monitor serivce
sprintf(context->result, ":%x", G_NODE.monitor_exit);
return context->result;
}
return NULL;
}
if (strcmp(cmd,"NAME") == 0) {
int size = strlen(param);
char name[size+1];
char handle[size+1];
sscanf(param,"%s %s",name,handle);
if (handle[0] != ':') {
return NULL;
}
uint32_t handle_id = strtoul(handle+1, NULL, 16);
if (handle_id == 0) {
return NULL;
}
if (name[0] == '.') {
return skynet_handle_namehandle(handle_id, name + 1);
} else {
struct remote_name *rname = skynet_malloc(sizeof(*rname));
_copy_name(rname->name, name);
rname->handle = handle_id;
skynet_harbor_register(rname);
}
return NULL;
}
if (strcmp(cmd,"NOW") == 0) {
uint32_t ti = skynet_gettime();
sprintf(context->result,"%u",ti);
return context->result;
}
if (strcmp(cmd,"EXIT") == 0) {
handle_exit(context, 0);
return NULL;
}
if (strcmp(cmd,"KILL") == 0) {
uint32_t handle = 0;
} else {
if (param[0] == ':') {
handle = strtoul(param+1, NULL, 16);
} else if (param[0] == '.') {
handle = skynet_handle_findname(param+1);
} else {
skynet_error(context, "Can't kill %s",param);
// todo : kill global service
}
if (handle) {
handle_exit(context, handle);
}
return NULL;
}
if (strcmp(cmd,"LAUNCH") == 0) {
size_t sz = strlen(param);
char tmp[sz+1];
strcpy(tmp,param);
char * args = tmp;
char * mod = strsep(&args, " \t\r\n");
args = strsep(&args, "\r\n");
struct skynet_context * inst = skynet_context_new(mod,args);
if (inst == NULL) {
return NULL;
} else {
_id_to_hex(context->result, inst->handle);
return context->result;
skynet_error(context, "Can't monitor %s",param);
// todo : monitor global service
}
}
G_NODE.monitor_exit = handle;
return NULL;
}
if (strcmp(cmd,"GETENV") == 0) {
return skynet_getenv(param);
}
static const char *
cmd_mqlen(struct skynet_context * context, const char * param) {
int len = skynet_mq_length(context->queue);
sprintf(context->result, "%d", len);
return context->result;
}
if (strcmp(cmd,"SETENV") == 0) {
size_t sz = strlen(param);
char key[sz+1];
int i;
for (i=0;param[i] != ' ' && param[i];i++) {
key[i] = param[i];
static struct command_func cmd_funcs[] = {
{ "TIMEOUT", cmd_timeout },
{ "REG", cmd_reg },
{ "QUERY", cmd_query },
{ "NAME", cmd_name },
{ "NOW", cmd_now },
{ "EXIT", cmd_exit },
{ "KILL", cmd_kill },
{ "LAUNCH", cmd_launch },
{ "GETENV", cmd_getenv },
{ "SETENV", cmd_setenv },
{ "STARTTIME", cmd_starttime },
{ "ENDLESS", cmd_endless },
{ "ABORT", cmd_abort },
{ "MONITOR", cmd_monitor },
{ "MQLEN", cmd_mqlen },
{ NULL, NULL },
};
const char *
skynet_command(struct skynet_context * context, const char * cmd , const char * param) {
struct command_func * method = &cmd_funcs[0];
while(method->name) {
if (strcmp(cmd, method->name) == 0) {
return method->func(context, param);
}
if (param[i] == '\0')
return NULL;
key[i] = '\0';
param += i+1;
skynet_setenv(key,param);
return NULL;
}
if (strcmp(cmd,"STARTTIME") == 0) {
uint32_t sec = skynet_gettime_fixsec();
sprintf(context->result,"%u",sec);
return context->result;
}
if (strcmp(cmd,"ENDLESS") == 0) {
if (context->endless) {
strcpy(context->result, "1");
context->endless = false;
return context->result;
}
return NULL;
}
if (strcmp(cmd,"ABORT") == 0) {
skynet_handle_retireall();
return NULL;
}
if (strcmp(cmd,"MONITOR") == 0) {
uint32_t handle=0;
if (param == NULL || param[0] == '\0') {
if (G_NODE.monitor_exit) {
// return current monitor serivce
sprintf(context->result, ":%x", G_NODE.monitor_exit);
return context->result;
}
return NULL;
} else {
if (param[0] == ':') {
handle = strtoul(param+1, NULL, 16);
} else if (param[0] == '.') {
handle = skynet_handle_findname(param+1);
} else {
skynet_error(context, "Can't monitor %s",param);
// todo : monitor global service
}
}
G_NODE.monitor_exit = handle;
return NULL;
}
if (strcmp(cmd, "MQLEN") == 0) {
int len = skynet_mq_length(context->queue);
sprintf(context->result, "%d", len);
return context->result;
++method;
}
return NULL;
@@ -550,7 +599,7 @@ skynet_sendname(struct skynet_context * context, const char * addr , int type, i
_filter_args(context, type, &session, (void **)&data, &sz);
struct remote_message * rmsg = skynet_malloc(sizeof(*rmsg));
_copy_name(rmsg->destination.name, addr);
copy_name(rmsg->destination.name, addr);
rmsg->destination.handle = 0;
rmsg->message = data;
rmsg->sz = sz;