From b6314b537f405c40dfd33887b8e5e1ad060d7b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E9=A3=8E?= Date: Thu, 8 Nov 2012 14:57:51 +0800 Subject: [PATCH] skynet abort --- lualib/skynet.lua | 4 ++++ service-src/service_harbor.c | 8 ++++---- service-src/service_master.c | 8 ++++---- service/abort.lua | 3 +++ skynet-src/skynet_handle.c | 20 ++++++++++++++++++++ skynet-src/skynet_handle.h | 1 + skynet-src/skynet_main.c | 2 ++ skynet-src/skynet_server.c | 28 +++++++++++++++++++++++++++- skynet-src/skynet_server.h | 1 + skynet-src/skynet_start.c | 31 ++++++++++++++++++------------- 10 files changed, 84 insertions(+), 22 deletions(-) create mode 100644 service/abort.lua diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 700ce1d7..b8f16f9d 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -584,4 +584,8 @@ function skynet.endless() return c.command("ENDLESS")~=nil end +function skynet.abort() + c.command("ABORT") +end + return skynet diff --git a/service-src/service_harbor.c b/service-src/service_harbor.c index 3b612e85..76d1fdca 100644 --- a/service-src/service_harbor.c +++ b/service-src/service_harbor.c @@ -181,12 +181,12 @@ static void _hash_delete(struct hashmap *hash) { int i; for (i=0;inode[i]; - while (*ptr) { - struct keyvalue * node = *ptr; - ptr = &node->next; + struct keyvalue * node = hash->node[i]; + while (node) { + struct keyvalue * next = node->next; _release_queue(node->queue); free(node); + node = next; } } free(hash); diff --git a/service-src/service_master.c b/service-src/service_master.c index 5af20be5..eaaffcd0 100644 --- a/service-src/service_master.c +++ b/service-src/service_master.c @@ -54,11 +54,11 @@ master_release(struct master * m) { free(m->remote_addr[i]); } for (i=0;imap.node[i]; - while (*ptr) { - struct name * node = *ptr; - ptr = &node->next; + struct name * node = m->map.node[i]; + while (node) { + struct name * next = node->next; free(node); + node = next; } } free(m); diff --git a/service/abort.lua b/service/abort.lua new file mode 100644 index 00000000..755675a6 --- /dev/null +++ b/service/abort.lua @@ -0,0 +1,3 @@ +local skynet = require "skynet" + +skynet.abort() diff --git a/skynet-src/skynet_handle.c b/skynet-src/skynet_handle.c index 8d74416f..1cfb23a1 100644 --- a/skynet-src/skynet_handle.c +++ b/skynet-src/skynet_handle.c @@ -93,6 +93,26 @@ skynet_handle_retire(uint32_t handle) { rwlock_wunlock(&s->lock); } +void +skynet_handle_retireall() { + struct handle_storage *s = H; + for (;;) { + int n=0; + int i; + for (i=0;islot_size;i++) { + rwlock_rlock(&s->lock); + struct skynet_context * ctx = s->slot[i]; + rwlock_runlock(&s->lock); + if (ctx != NULL) { + ++n; + skynet_handle_retire(skynet_context_handle(ctx)); + } + } + if (n==0) + return; + } +} + struct skynet_context * skynet_handle_grab(uint32_t handle) { struct handle_storage *s = H; diff --git a/skynet-src/skynet_handle.h b/skynet-src/skynet_handle.h index ce5d4976..a39b47bb 100644 --- a/skynet-src/skynet_handle.h +++ b/skynet-src/skynet_handle.h @@ -10,6 +10,7 @@ struct skynet_context; uint32_t skynet_handle_register(struct skynet_context *); void skynet_handle_retire(uint32_t handle); struct skynet_context * skynet_handle_grab(uint32_t handle); +void skynet_handle_retireall(); uint32_t skynet_handle_findname(const char * name); const char * skynet_handle_namehandle(uint32_t handle, const char *name); diff --git a/skynet-src/skynet_main.c b/skynet-src/skynet_main.c index 49db5147..ce10e94d 100644 --- a/skynet-src/skynet_main.c +++ b/skynet-src/skynet_main.c @@ -114,5 +114,7 @@ main(int argc, char *argv[]) { skynet_start(&config); + printf("skynet exit\n"); + return 0; } diff --git a/skynet-src/skynet_server.c b/skynet-src/skynet_server.c index 7383f732..9ed8bab1 100644 --- a/skynet-src/skynet_server.c +++ b/skynet-src/skynet_server.c @@ -49,6 +49,23 @@ struct skynet_context { CHECKCALLING_DECL }; +static int g_total_context = 0; + +int +skynet_context_total() { + return g_total_context; +} + +static void +_context_inc() { + __sync_fetch_and_add(&g_total_context,1); +} + +static void +_context_dec() { + __sync_fetch_and_sub(&g_total_context,1); +} + static void _id_to_hex(char * str, uint32_t id) { int i; @@ -96,7 +113,10 @@ skynet_context_new(const char * name, const char *param) { ctx->init = true; } skynet_mq_force_push(queue); - printf("[:%x] launch %s %s\n",ret->handle, name, param ? param : ""); + if (ret) { + printf("[:%x] launch %s %s\n",ret->handle, name, param ? param : ""); + } + _context_inc(); return ret; } else { skynet_context_release(ctx); @@ -121,6 +141,7 @@ _delete_context(struct skynet_context *ctx) { skynet_module_instance_release(ctx->mod, ctx->instance); skynet_mq_mark_release(ctx->queue); free(ctx); + _context_dec(); } struct skynet_context * @@ -480,6 +501,11 @@ skynet_command(struct skynet_context * context, const char * cmd , const char * return NULL; } + if (strcmp(cmd,"ABORT") == 0) { + skynet_handle_retireall(); + return NULL; + } + return NULL; } diff --git a/skynet-src/skynet_server.h b/skynet-src/skynet_server.h index ff1e11ac..604529fe 100644 --- a/skynet-src/skynet_server.h +++ b/skynet-src/skynet_server.h @@ -17,6 +17,7 @@ int skynet_context_push(uint32_t handle, struct skynet_message *message); void skynet_context_send(struct skynet_context * context, void * msg, size_t sz, uint32_t source, int type, int session); int skynet_context_newsession(struct skynet_context *); int skynet_context_message_dispatch(struct skynet_monitor *); // return 1 when block +int skynet_context_total(); void skynet_context_endless(uint32_t handle); // for monitor diff --git a/skynet-src/skynet_start.c b/skynet-src/skynet_start.c index f593ca87..5df90fef 100644 --- a/skynet-src/skynet_start.c +++ b/skynet-src/skynet_start.c @@ -20,6 +20,8 @@ struct monitor { struct skynet_monitor ** m; }; +#define CHECK_ABORT if (skynet_context_total()==0) break; + static void * _monitor(void *p) { struct monitor * m = p; @@ -29,8 +31,14 @@ _monitor(void *p) { for (i=0;im[i]); } + CHECK_ABORT sleep(5); } + for (i=0;im[i]); + } + free(m->m); + free(m); return NULL; } @@ -39,6 +47,7 @@ static void * _timer(void *p) { for (;;) { skynet_updatetime(); + CHECK_ABORT usleep(2500); } return NULL; @@ -49,6 +58,7 @@ _worker(void *p) { struct skynet_monitor *sm = p; for (;;) { if (skynet_context_message_dispatch(sm)) { + CHECK_ABORT usleep(1000); } } @@ -59,29 +69,24 @@ static void _start(int thread) { pthread_t pid[thread+2]; - struct monitor m; - m.count = thread; - m.m = malloc(thread * sizeof(struct skynet_monitor *)); + struct monitor *m = malloc(sizeof(*m)); + m->count = thread; + m->m = malloc(thread * sizeof(struct skynet_monitor *)); int i; for (i=0;im[i] = skynet_monitor_new(); } - pthread_create(&pid[0], NULL, _timer, NULL); - pthread_create(&pid[1], NULL, _monitor, &m); + pthread_create(&pid[0], NULL, _monitor, m); + pthread_create(&pid[1], NULL, _timer, NULL); for (i=0;im[i]); } - for (i=0;i