From 7dff50d21d522722a0534f04b31076c25f9fcde7 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Mon, 12 May 2014 11:04:58 +0800 Subject: [PATCH] merge pr 103 --- skynet-src/skynet_server.c | 371 +++++++++++++++++++++---------------- 1 file changed, 210 insertions(+), 161 deletions(-) diff --git a/skynet-src/skynet_server.c b/skynet-src/skynet_server.c index 9eed0435..4bc7b66a 100644 --- a/skynet-src/skynet_server.c +++ b/skynet-src/skynet_server.c @@ -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;ihandle, 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;