From: Cyrill Gorcunov <gorcunov@gmail.com> To: tml <tarantool-patches@dev.tarantool.org> Cc: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>, Alexander Turenko <alexander.turenko@tarantool.org> Subject: [Tarantool-patches] [PATCH v4 2/6] box/func: provide module_sym_call Date: Thu, 1 Oct 2020 16:51:09 +0300 [thread overview] Message-ID: <20201001135113.329664-3-gorcunov@gmail.com> (raw) In-Reply-To: <20201001135113.329664-1-gorcunov@gmail.com> This helpers allow to execute a function bound to module symbol without claiming to provide credentials and being registered in "_func" space. This will be needed to execute unregistered C functions. Part-of #4642 Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> --- src/box/func.c | 78 +++++++++++++++++++++++++++++--------------------- src/box/func.h | 14 +++++++++ 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/box/func.c b/src/box/func.c index 75d2abb5f..452866a5d 100644 --- a/src/box/func.c +++ b/src/box/func.c @@ -408,6 +408,50 @@ module_sym_unload(struct module_sym *mod_sym) mod_sym->addr = NULL; } +int +module_sym_call(struct module_sym *mod_sym, struct port *args, struct port *ret) +{ + if (mod_sym->addr == NULL) { + if (module_sym_load(mod_sym) != 0) + return -1; + } + + struct region *region = &fiber()->gc; + size_t region_svp = region_used(region); + uint32_t data_sz; + const char *data = port_get_msgpack(args, &data_sz); + if (data == NULL) + return -1; + + port_c_create(ret); + box_function_ctx_t ctx = { + .port = ret, + }; + + /* + * Module can be changed after function reload. Also + * keep in mind that stored C procedure may yield inside. + */ + struct module *module = mod_sym->module; + assert(module != NULL); + ++module->calls; + int rc = mod_sym->addr(&ctx, data, data + data_sz); + --module->calls; + module_gc(module); + region_truncate(region, region_svp); + + if (rc != 0) { + if (diag_last_error(&fiber()->diag) == NULL) { + /* Stored procedure forget to set diag */ + diag_set(ClientError, ER_PROC_C, "unknown error"); + } + port_destroy(ret); + return -1; + } + + return rc; +} + int module_reload(const char *package, const char *package_end, struct module **module) { @@ -544,39 +588,9 @@ func_c_call(struct func *base, struct port *args, struct port *ret) { assert(base->vtab == &func_c_vtab); assert(base != NULL && base->def->language == FUNC_LANGUAGE_C); - struct func_c *func = (struct func_c *) base; - if (func->mod_sym.addr == NULL) { - if (module_sym_load(&func->mod_sym) != 0) - return -1; - } - - struct region *region = &fiber()->gc; - size_t region_svp = region_used(region); - uint32_t data_sz; - const char *data = port_get_msgpack(args, &data_sz); - if (data == NULL) - return -1; - - port_c_create(ret); - box_function_ctx_t ctx = { ret }; - /* Module can be changed after function reload. */ - struct module *module = func->mod_sym.module; - assert(module != NULL); - ++module->calls; - int rc = func->mod_sym.addr(&ctx, data, data + data_sz); - --module->calls; - module_gc(module); - region_truncate(region, region_svp); - if (rc != 0) { - if (diag_last_error(&fiber()->diag) == NULL) { - /* Stored procedure forget to set diag */ - diag_set(ClientError, ER_PROC_C, "unknown error"); - } - port_destroy(ret); - return -1; - } - return rc; + struct func_c *func = (struct func_c *) base; + return module_sym_call(&func->mod_sym, args, ret); } static struct func_vtab func_c_vtab = { diff --git a/src/box/func.h b/src/box/func.h index acf2df9a9..35f4e320c 100644 --- a/src/box/func.h +++ b/src/box/func.h @@ -151,6 +151,20 @@ module_sym_load(struct module_sym *mod_sym); void module_sym_unload(struct module_sym *mod_sym); +/** + * Execute a module symbol call. + * + * @param mod_sym module symbol pointer. + * @param args arguments to pass to the callee. + * @param ret execution results passed to the caller. + * + * @retval -1 on error. + * @retval 0 on success. + */ +int +module_sym_call(struct module_sym *mod_sym, struct port *args, + struct port *ret); + /** * Reload dynamically loadable module. * -- 2.26.2
next prev parent reply other threads:[~2020-10-01 13:51 UTC|newest] Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-01 13:51 [Tarantool-patches] [PATCH v4 0/6] box/func: implement cfunc Lua module Cyrill Gorcunov 2020-10-01 13:51 ` [Tarantool-patches] [PATCH v4 1/6] box/func: factor out c function entry structure Cyrill Gorcunov 2020-10-01 13:51 ` Cyrill Gorcunov [this message] 2020-10-01 13:51 ` [Tarantool-patches] [PATCH v4 3/6] box/func: more detailed error in module reloading Cyrill Gorcunov 2020-10-01 13:51 ` [Tarantool-patches] [PATCH v4 4/6] box/func: export func_split_name helper Cyrill Gorcunov 2020-10-01 13:51 ` [Tarantool-patches] [PATCH v4 5/6] box/func: implement cfunc Lua module Cyrill Gorcunov 2020-10-03 13:55 ` Vladislav Shpilevoy 2020-10-05 10:31 ` Cyrill Gorcunov 2020-10-05 21:59 ` Vladislav Shpilevoy 2020-10-06 12:55 ` Cyrill Gorcunov 2020-10-01 13:51 ` [Tarantool-patches] [PATCH v4 6/6] test: box/cfunc -- add simple module test Cyrill Gorcunov 2020-10-03 13:55 ` Vladislav Shpilevoy 2020-10-03 13:55 ` [Tarantool-patches] [PATCH v4 0/6] box/func: implement cfunc Lua module Vladislav Shpilevoy 2020-10-05 11:51 ` Cyrill Gorcunov 2020-10-05 21:59 ` Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20201001135113.329664-3-gorcunov@gmail.com \ --to=gorcunov@gmail.com \ --cc=alexander.turenko@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v4 2/6] box/func: provide module_sym_call' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox