Skip to content

Commit

Permalink
feat(melang): add new script function to kill coroutine task and refa…
Browse files Browse the repository at this point in the history
…ctor function Eval to support alias
  • Loading branch information
Water-Melon committed Oct 24, 2023
1 parent a408c29 commit 840f457
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 12 deletions.
12 changes: 9 additions & 3 deletions docs/Melon Developer Guide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3829,13 +3829,19 @@ Their definitions can be found in melon/include/mln_types.h.
Dynamic library must contain the entrance function named 'init', its prototype is:
mln_lang_var_t *init(mln_lang_ctx_t *);

<5> Eval(val, data, in_string);
<5> Eval(val, data, in_string, alias);
val - a file path or a code string.
data - the data that we want to deliver to the new coroutine.
on_string - a optional argument. If is set and its value is *true*, *val* is a code string.
in_string - a optional argument. If is set and its value is *true*, *val* is a code string.
Otherwise, *val* is a file path.
alias - the name of new coroutine task, and it can be omitted if it is not needed.

<6> Pipe(op);
<6> Kill(alias);
Kill the running coroutine task specified by 'alias'.
alias - the name of running coroutine task given by function 'Eval'.
This function always return a 'nil'.

<7> Pipe(op);
Receive message sent by 'mln_lang_ctx_pipe_send' from C code.
op - has three values:
"subscribe" - subscribe message delivery.
Expand Down
5 changes: 4 additions & 1 deletion include/mln_lang.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ struct mln_lang_s {
mln_lang_run_ctl_t signal;
mln_lang_run_ctl_t clear;
ev_fd_handler launcher;
mln_rbtree_t *alias_set;
pthread_mutex_t lock;
};

Expand Down Expand Up @@ -215,6 +216,7 @@ struct mln_lang_ctx_s {
mln_lang_symbol_node_t *sym_head;
mln_lang_symbol_node_t *sym_tail;
pthread_t owner;
mln_string_t *alias;
mln_u32_t sym_count:16;
mln_u32_t ret_flag:1;
/*flags for operator overloading*/
Expand Down Expand Up @@ -453,10 +455,11 @@ extern mln_lang_t *mln_lang_new(mln_event_t *ev, mln_lang_run_ctl_t signal, mln_
extern void mln_lang_free(mln_lang_t *lang);
extern mln_lang_ctx_t *
mln_lang_job_new(mln_lang_t *lang, \
mln_string_t *alias, \
mln_u32_t type, \
mln_string_t *data, \
void *udata, \
mln_lang_return_handler handler) __NONNULL2(1,3);
mln_lang_return_handler handler) __NONNULL2(1,4);
extern void mln_lang_job_free(mln_lang_ctx_t *ctx);
extern void mln_lang_funccall_val_object_add(mln_lang_funccall_val_t *func, mln_lang_val_t *obj_val) __NONNULL2(1,2);
/*
Expand Down
170 changes: 163 additions & 7 deletions src/mln_lang.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ MLN_CHAIN_FUNC_DEFINE(mln_lang_var, \
static inline void, \
prev, \
next);
static int mln_lang_ctx_alias_cmp(mln_lang_ctx_t *ctx1, mln_lang_ctx_t *ctx2);
static inline mln_lang_ctx_t *
__mln_lang_job_new(mln_lang_t *lang, \
mln_string_t *alias, \
mln_u32_t type, \
mln_string_t *data, \
void *udata, \
Expand All @@ -99,7 +101,7 @@ mln_lang_ast_cache_new(mln_lang_t *lang, mln_lang_stm_t *stm, mln_string_t *code
static inline void
mln_lang_ast_cache_free(mln_lang_ast_cache_t *cache);
static inline mln_lang_ctx_t *
mln_lang_ctx_new(mln_lang_t *lang, void *data, mln_string_t *filename, mln_u32_t type, mln_string_t *content);
mln_lang_ctx_new(mln_lang_t *lang, void *data, mln_string_t *filename, mln_u32_t type, mln_string_t *content, mln_string_t *alias);
static inline void mln_lang_ctx_free(mln_lang_ctx_t *ctx);
static inline mln_lang_set_detail_t *
mln_lang_ctx_get_class(mln_lang_ctx_t *ctx);
Expand Down Expand Up @@ -257,7 +259,9 @@ static int mln_lang_func_dump(mln_lang_ctx_t *ctx);
static int mln_lang_func_watch(mln_lang_ctx_t *ctx);
static int mln_lang_func_unwatch(mln_lang_ctx_t *ctx);
static int mln_lang_func_eval(mln_lang_ctx_t *ctx);
static int mln_lang_func_kill(mln_lang_ctx_t *ctx);
static mln_lang_var_t *mln_lang_func_eval_process(mln_lang_ctx_t *ctx);
static mln_lang_var_t *mln_lang_func_kill_process(mln_lang_ctx_t *ctx);
static int mln_lang_internal_func_installer(mln_lang_ctx_t *ctx);
static mln_lang_var_t *mln_lang_func_dump_process(mln_lang_ctx_t *ctx);
static mln_lang_var_t *mln_lang_func_watch_process(mln_lang_ctx_t *ctx);
Expand Down Expand Up @@ -559,6 +563,7 @@ mln_lang_t *mln_lang_new(mln_event_t *ev, mln_lang_run_ctl_t signal, mln_lang_ru
lang->signal = signal;
lang->launcher = mln_lang_run_handler;
lang->clear = clear;
lang->alias_set = NULL;
if (pthread_mutex_init(&lang->lock, NULL) != 0) {
mln_alloc_destroy(pool);
return NULL;
Expand All @@ -576,6 +581,12 @@ mln_lang_t *mln_lang_new(mln_event_t *ev, mln_lang_run_ctl_t signal, mln_lang_ru
mln_lang_free(lang);
return NULL;
}
rbattr.cmp = (rbtree_cmp)mln_lang_ctx_alias_cmp;
rbattr.data_free = NULL;
if ((lang->alias_set = mln_rbtree_new(&rbattr)) == NULL) {
mln_lang_free(lang);
return NULL;
}
return lang;
}

Expand Down Expand Up @@ -606,6 +617,7 @@ void mln_lang_free(mln_lang_t *lang)
mln_lang_ast_cache_chain_del(&(lang->cache_head), &(lang->cache_tail), cache);
mln_lang_ast_cache_free(cache);
}
if (lang->alias_set != NULL) mln_rbtree_free(lang->alias_set);

pthread_mutex_unlock(&lang->lock);
pthread_mutex_destroy(&lang->lock);
Expand Down Expand Up @@ -760,7 +772,7 @@ mln_lang_ast_cache_search(mln_lang_t *lang, mln_u32_t type, mln_string_t *conten


static inline mln_lang_ctx_t *
mln_lang_ctx_new(mln_lang_t *lang, void *data, mln_string_t *filename, mln_u32_t type, mln_string_t *content)
mln_lang_ctx_new(mln_lang_t *lang, void *data, mln_string_t *filename, mln_u32_t type, mln_string_t *content, mln_string_t *alias)
{
mln_lang_ctx_t *ctx;
struct mln_rbtree_attr rbattr;
Expand Down Expand Up @@ -798,6 +810,7 @@ mln_lang_ctx_new(mln_lang_t *lang, void *data, mln_string_t *filename, mln_u32_t
ctx->ref = 0;
ctx->filename = NULL;
ctx->symbols = NULL;
ctx->alias = NULL;
rbattr.pool = ctx->pool;
rbattr.pool_alloc = (rbtree_pool_alloc_handler)mln_alloc_m;
rbattr.pool_free = (rbtree_pool_free_handler)mln_alloc_free;
Expand Down Expand Up @@ -872,14 +885,43 @@ mln_lang_ctx_new(mln_lang_t *lang, void *data, mln_string_t *filename, mln_u32_t
mln_lang_ctx_free(ctx);
return NULL;
}

if (alias != NULL) {
mln_rbtree_node_t *rn;

if ((ctx->alias = mln_string_pool_dup(ctx->pool, alias)) == NULL) {
mln_lang_ctx_free(ctx);
return NULL;
}

rn = mln_rbtree_search(ctx->lang->alias_set, ctx);
if (!mln_rbtree_null(rn, ctx->lang->alias_set)) {
mln_lang_ctx_free(ctx);
return NULL;
}
if ((rn = mln_rbtree_node_new(ctx->lang->alias_set, ctx)) == NULL) {
mln_lang_ctx_free(ctx);
return NULL;
}
mln_rbtree_insert(ctx->lang->alias_set, rn);
}
return ctx;
}

static inline void mln_lang_ctx_free(mln_lang_ctx_t *ctx)
{
if (ctx == NULL) return;
mln_lang_symbol_node_t *sym;
mln_rbtree_node_t *rn;

if (ctx->alias != NULL) {
rn = mln_rbtree_search(ctx->lang->alias_set, ctx);
if (!mln_rbtree_null(rn, ctx->lang->alias_set)) {
mln_rbtree_delete(ctx->lang->alias_set, rn);
mln_rbtree_node_free(ctx->lang->alias_set, rn);
}
mln_string_free(ctx->alias);
}
while ((sym = ctx->sym_head) != NULL) {
mln_lang_sym_chain_del(&ctx->sym_head, &ctx->sym_tail, sym);
sym->ctx = NULL;
Expand Down Expand Up @@ -915,6 +957,11 @@ static inline void mln_lang_ctx_free(mln_lang_ctx_t *ctx)
mln_alloc_free(ctx);
}

static int mln_lang_ctx_alias_cmp(mln_lang_ctx_t *ctx1, mln_lang_ctx_t *ctx2)
{
return mln_string_strcmp(ctx1->alias, ctx2->alias);
}

void mln_lang_ctx_suspend(mln_lang_ctx_t *ctx)
{
if (ctx->ref) return;
Expand Down Expand Up @@ -985,26 +1032,28 @@ int mln_lang_ctx_global_var_add(mln_lang_ctx_t *ctx, mln_string_t *name, void *v

mln_lang_ctx_t *
mln_lang_job_new(mln_lang_t *lang, \
mln_string_t *alias, \
mln_u32_t type, \
mln_string_t *data, \
void *udata, \
mln_lang_return_handler handler)
{
mln_lang_ctx_t *ctx;
pthread_mutex_lock(&lang->lock);
ctx = __mln_lang_job_new(lang, type, data, udata, handler);
ctx = __mln_lang_job_new(lang, alias, type, data, udata, handler);
pthread_mutex_unlock(&lang->lock);
return ctx;
}

static inline mln_lang_ctx_t *
__mln_lang_job_new(mln_lang_t *lang, \
mln_string_t *alias, \
mln_u32_t type, \
mln_string_t *data, \
void *udata, \
mln_lang_return_handler handler)
{
mln_lang_ctx_t *ctx = mln_lang_ctx_new(lang, udata, type==M_INPUT_T_FILE? data: NULL, type, data);
mln_lang_ctx_t *ctx = mln_lang_ctx_new(lang, udata, type==M_INPUT_T_FILE? data: NULL, type, data, alias);
if (ctx == NULL) {
return NULL;
}
Expand Down Expand Up @@ -6335,6 +6384,7 @@ static int mln_lang_internal_func_installer(mln_lang_ctx_t *ctx)
if (mln_lang_func_watch(ctx) < 0) return -1;
if (mln_lang_func_unwatch(ctx) < 0) return -1;
if (mln_lang_func_eval(ctx) < 0) return -1;
if (mln_lang_func_kill(ctx) < 0) return -1;
if (mln_lang_func_pipe(ctx) < 0) return -1;
return 0;
}
Expand Down Expand Up @@ -6684,6 +6734,7 @@ static int mln_lang_func_eval(mln_lang_ctx_t *ctx)
mln_string_t v1 = mln_string("val");
mln_string_t v2 = mln_string("data");
mln_string_t v3 = mln_string("in_string");
mln_string_t v4 = mln_string("alias");
if ((func = mln_lang_func_detail_new(ctx, M_FUNC_INTERNAL, (void *)mln_lang_func_eval_process, NULL, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
return -1;
Expand Down Expand Up @@ -6727,6 +6778,19 @@ static int mln_lang_func_eval(mln_lang_ctx_t *ctx)
}
mln_lang_var_chain_add(&(func->args_head), &(func->args_tail), var);
++func->nargs;
if ((val = mln_lang_val_new(ctx, M_LANG_VAL_TYPE_NIL, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_func_detail_free(func);
return -1;
}
if ((var = mln_lang_var_new(ctx, &v4, M_LANG_VAR_NORMAL, val, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_val_free(val);
mln_lang_func_detail_free(func);
return -1;
}
mln_lang_var_chain_add(&(func->args_head), &(func->args_tail), var);
++func->nargs;
if ((val = mln_lang_val_new(ctx, M_LANG_VAL_TYPE_FUNC, func)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_func_detail_free(func);
Expand All @@ -6751,7 +6815,8 @@ static mln_lang_var_t *mln_lang_func_eval_process(mln_lang_ctx_t *ctx)
mln_string_t v1 = mln_string("val");
mln_string_t v2 = mln_string("data");
mln_string_t v3 = mln_string("in_string");
mln_string_t data_name = mln_string("EVAL_DATA"), *dup;
mln_string_t v4 = mln_string("alias");
mln_string_t data_name = mln_string("EVAL_DATA"), *dup, *alias;
mln_lang_symbol_node_t *sym;
mln_lang_val_t *val1, *val2;
mln_s32_t type, type3;
Expand Down Expand Up @@ -6801,9 +6866,27 @@ static mln_lang_var_t *mln_lang_func_eval_process(mln_lang_ctx_t *ctx)
} else {
job_type = M_INPUT_T_FILE;
}
/*arg4*/
if ((sym = mln_lang_symbol_node_search(ctx, &v4, 1)) == NULL) {
ASSERT(0);
mln_lang_errmsg(ctx, "Argument 4 missing.");
return NULL;
}
if (sym->type != M_LANG_SYMBOL_VAR) {
mln_lang_errmsg(ctx, "Invalid type of argument 4.");
return NULL;
}
if (mln_lang_var_val_type_get(sym->data.var) == M_LANG_VAL_TYPE_NIL) {
alias = NULL;
} else if (mln_lang_var_val_type_get(sym->data.var) == M_LANG_VAL_TYPE_STRING) {
alias = mln_lang_var_val_get(sym->data.var)->data.s;
} else {
mln_lang_errmsg(ctx, "Invalid type of argument 4.");
return NULL;
}
/*create job ctx*/
if ((newctx = __mln_lang_job_new(ctx->lang, job_type, val1->data.s, NULL, NULL)) == NULL) {
mln_lang_errmsg(ctx, "Eval failed..");
if ((newctx = __mln_lang_job_new(ctx->lang, alias, job_type, val1->data.s, NULL, NULL)) == NULL) {
mln_lang_errmsg(ctx, "Eval failed.");
return NULL;
}
switch (type) {
Expand Down Expand Up @@ -6854,6 +6937,79 @@ static mln_lang_var_t *mln_lang_func_eval_process(mln_lang_ctx_t *ctx)
return ret_var;
}

static int mln_lang_func_kill(mln_lang_ctx_t *ctx)
{
mln_lang_val_t *val;
mln_lang_var_t *var;
mln_lang_func_detail_t *func;
mln_string_t funcname = mln_string("Kill");
mln_string_t v1 = mln_string("alias");
if ((func = mln_lang_func_detail_new(ctx, M_FUNC_INTERNAL, (void *)mln_lang_func_kill_process, NULL, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
return -1;
}
if ((val = mln_lang_val_new(ctx, M_LANG_VAL_TYPE_NIL, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_func_detail_free(func);
return -1;
}
if ((var = mln_lang_var_new(ctx, &v1, M_LANG_VAR_NORMAL, val, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_val_free(val);
mln_lang_func_detail_free(func);
return -1;
}
mln_lang_var_chain_add(&(func->args_head), &(func->args_tail), var);
++func->nargs;
if ((val = mln_lang_val_new(ctx, M_LANG_VAL_TYPE_FUNC, func)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_func_detail_free(func);
return -1;
}
if ((var = mln_lang_var_new(ctx, &funcname, M_LANG_VAR_NORMAL, val, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_val_free(val);
return -1;
}
if (mln_lang_symbol_node_join(ctx, M_LANG_SYMBOL_VAR, var) < 0) {
mln_lang_errmsg(ctx, "No memory.");
mln_lang_var_free(var);
return -1;
}
return 0;
}

static mln_lang_var_t *mln_lang_func_kill_process(mln_lang_ctx_t *ctx)
{
mln_lang_var_t *ret_var = NULL;
mln_string_t v1 = mln_string("alias");
mln_lang_symbol_node_t *sym;
mln_lang_ctx_t *killed_ctx, tmp;
mln_rbtree_node_t *rn;

if ((sym = mln_lang_symbol_node_search(ctx, &v1, 1)) == NULL) {
ASSERT(0);
mln_lang_errmsg(ctx, "Argument 1 missing.");
return NULL;
}
if (sym->type != M_LANG_SYMBOL_VAR || mln_lang_var_val_type_get(sym->data.var) != M_LANG_VAL_TYPE_STRING) {
mln_lang_errmsg(ctx, "Invalid type of argument 1.");
return NULL;
}
tmp.alias = mln_lang_var_val_get(sym->data.var)->data.s;

rn = mln_rbtree_search(ctx->lang->alias_set, &tmp);
if (!mln_rbtree_null(rn, ctx->lang->alias_set)) {
killed_ctx = (mln_lang_ctx_t *)mln_rbtree_node_data_get(rn);
__mln_lang_job_free(killed_ctx);
}
if ((ret_var = mln_lang_var_create_nil(ctx, NULL)) == NULL) {
mln_lang_errmsg(ctx, "No memory.");
return NULL;
}
return ret_var;
}


/*
* mln_lang_gc_item_t
Expand Down
2 changes: 1 addition & 1 deletion src/mln_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ int mln_trace_init(mln_event_t *ev, mln_string_t *path)
}
mln_lang_cache_set(trace_lang);

trace_ctx = mln_lang_job_new(trace_lang, M_INPUT_T_FILE, path, NULL, mln_trace_lang_ctx_return_handler);
trace_ctx = mln_lang_job_new(trace_lang, NULL, M_INPUT_T_FILE, path, NULL, mln_trace_lang_ctx_return_handler);
if (trace_ctx == NULL) {
goto err3;
}
Expand Down

0 comments on commit 840f457

Please sign in to comment.