mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
skynet_context: skynet_context_new 改为返回 handle 避免调用者拿到悬垂指针 (#2095)
* skynet_context: skynet_context_new 改为返回 handle 避免调用者拿到悬垂指针 * 推迟 skynet_handle_grab(logger_handle) 到 bootstrap 失败阶段 --------- Co-authored-by: efve.zff <efve.zff@alibaba-inc.com>
This commit is contained in:
@@ -121,22 +121,22 @@ drop_message(struct skynet_message *msg, void *ud) {
|
||||
skynet_send(NULL, source, msg->source, PTYPE_ERROR, msg->session, NULL, 0);
|
||||
}
|
||||
|
||||
struct skynet_context *
|
||||
uint32_t
|
||||
skynet_context_new(const char * name, const char *param) {
|
||||
struct skynet_module * mod = skynet_module_query(name);
|
||||
|
||||
if (mod == NULL)
|
||||
return NULL;
|
||||
return 0;
|
||||
|
||||
void *inst = skynet_module_instance_create(mod);
|
||||
if (inst == NULL)
|
||||
return NULL;
|
||||
return 0;
|
||||
struct skynet_context * ctx = skynet_malloc(sizeof(*ctx));
|
||||
CHECKCALLING_INIT(ctx)
|
||||
|
||||
ctx->mod = mod;
|
||||
ctx->instance = inst;
|
||||
ATOM_INIT(&ctx->ref , 2);
|
||||
ATOM_INIT(&ctx->ref , 2); // skynet_handle_register + skynet_module_instance_init
|
||||
ctx->cb = NULL;
|
||||
ctx->cb_ud = NULL;
|
||||
ctx->session_id = 0;
|
||||
@@ -151,8 +151,9 @@ skynet_context_new(const char * name, const char *param) {
|
||||
ctx->profile = G_NODE.profile;
|
||||
// Should set to 0 first to avoid skynet_handle_retireall get an uninitialized handle
|
||||
ctx->handle = 0;
|
||||
ctx->handle = skynet_handle_register(ctx);
|
||||
struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
|
||||
const uint32_t handle = skynet_handle_register(ctx);
|
||||
ctx->handle = handle;
|
||||
struct message_queue * queue = ctx->queue = skynet_mq_create(handle);
|
||||
// init function maybe use ctx->handle, so it must init at last
|
||||
context_inc();
|
||||
|
||||
@@ -160,15 +161,11 @@ skynet_context_new(const char * name, const char *param) {
|
||||
int r = skynet_module_instance_init(mod, inst, ctx, param);
|
||||
CHECKCALLING_END(ctx)
|
||||
if (r == 0) {
|
||||
struct skynet_context * ret = skynet_context_release(ctx);
|
||||
if (ret) {
|
||||
ctx->init = true;
|
||||
}
|
||||
skynet_globalmq_push(queue);
|
||||
if (ret) {
|
||||
skynet_error(ret, "LAUNCH %s %s", name, param ? param : "");
|
||||
}
|
||||
return ret;
|
||||
skynet_error(ctx, "LAUNCH %s %s", name, param ? param : "");
|
||||
skynet_context_release(ctx);
|
||||
return handle;
|
||||
} else {
|
||||
skynet_error(ctx, "error: launch %s FAILED", name);
|
||||
uint32_t handle = ctx->handle;
|
||||
@@ -176,7 +173,7 @@ skynet_context_new(const char * name, const char *param) {
|
||||
skynet_handle_retire(handle);
|
||||
struct drop_t d = { handle };
|
||||
skynet_mq_release(queue, drop_message, &d);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,13 +214,11 @@ delete_context(struct skynet_context *ctx) {
|
||||
context_dec();
|
||||
}
|
||||
|
||||
struct skynet_context *
|
||||
void
|
||||
skynet_context_release(struct skynet_context *ctx) {
|
||||
if (ATOM_FDEC(&ctx->ref) == 1) {
|
||||
delete_context(ctx);
|
||||
return NULL;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -488,11 +483,11 @@ cmd_launch(struct skynet_context * context, const char * 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) {
|
||||
const uint32_t handle = skynet_context_new(mod,args);
|
||||
if (handle == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
id_to_hex(context->result, inst->handle);
|
||||
id_to_hex(context->result, handle);
|
||||
return context->result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ struct skynet_context;
|
||||
struct skynet_message;
|
||||
struct skynet_monitor;
|
||||
|
||||
struct skynet_context * skynet_context_new(const char * name, const char * parm);
|
||||
uint32_t skynet_context_new(const char * name, const char * parm);
|
||||
void skynet_context_grab(struct skynet_context *);
|
||||
void skynet_context_reserve(struct skynet_context *ctx);
|
||||
struct skynet_context * skynet_context_release(struct skynet_context *);
|
||||
void skynet_context_release(struct skynet_context *);
|
||||
uint32_t skynet_context_handle(struct skynet_context *);
|
||||
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);
|
||||
|
||||
@@ -231,7 +231,7 @@ start(int thread) {
|
||||
}
|
||||
|
||||
static void
|
||||
bootstrap(struct skynet_context * logger, const char * cmdline) {
|
||||
bootstrap(uint32_t logger_handle, const char * cmdline) {
|
||||
int sz = strlen(cmdline);
|
||||
char name[sz+1];
|
||||
char args[sz+1];
|
||||
@@ -246,10 +246,14 @@ bootstrap(struct skynet_context * logger, const char * cmdline) {
|
||||
} else {
|
||||
args[0] = '\0';
|
||||
}
|
||||
struct skynet_context *ctx = skynet_context_new(name, args);
|
||||
if (ctx == NULL) {
|
||||
const uint32_t handle = skynet_context_new(name, args);
|
||||
if (handle == 0) {
|
||||
struct skynet_context *logger = skynet_handle_grab(logger_handle);
|
||||
if (logger != NULL) {
|
||||
skynet_error(NULL, "Bootstrap error : %s\n", cmdline);
|
||||
skynet_context_dispatchall(logger);
|
||||
skynet_context_release(logger);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -276,15 +280,15 @@ skynet_start(struct skynet_config * config) {
|
||||
skynet_socket_init();
|
||||
skynet_profile_enable(config->profile);
|
||||
|
||||
struct skynet_context *ctx = skynet_context_new(config->logservice, config->logger);
|
||||
if (ctx == NULL) {
|
||||
const uint32_t logger_handle = skynet_context_new(config->logservice, config->logger);
|
||||
if (logger_handle == 0) {
|
||||
fprintf(stderr, "Can't launch %s service\n", config->logservice);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
skynet_handle_namehandle(skynet_context_handle(ctx), "logger");
|
||||
skynet_handle_namehandle(logger_handle, "logger");
|
||||
|
||||
bootstrap(ctx, config->bootstrap);
|
||||
bootstrap(logger_handle, config->bootstrap);
|
||||
|
||||
start(config->thread);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user