From: Cyrill Gorcunov <gorcunov@gmail.com>
To: tml <tarantool-patches@dev.tarantool.org>
Cc: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Subject: [Tarantool-patches] [PATCH v5 2/6] box/func: provide module_sym_call
Date: Fri, 9 Oct 2020 00:36:04 +0300 [thread overview]
Message-ID: <20201008213608.1022476-3-gorcunov@gmail.com> (raw)
In-Reply-To: <20201008213608.1022476-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-08 21:36 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-08 21:36 [Tarantool-patches] [PATCH v5 0/6] box/cbox: implement cfunc Lua module Cyrill Gorcunov
2020-10-08 21:36 ` [Tarantool-patches] [PATCH v5 1/6] box/func: factor out c function entry structure Cyrill Gorcunov
2020-10-08 21:36 ` Cyrill Gorcunov [this message]
2020-10-08 21:36 ` [Tarantool-patches] [PATCH v5 3/6] box/func: more detailed error in module reloading Cyrill Gorcunov
2020-10-08 21:36 ` [Tarantool-patches] [PATCH v5 4/6] box/func: export func_split_name helper Cyrill Gorcunov
2020-10-08 21:36 ` [Tarantool-patches] [PATCH v5 5/6] box/cbox: implement cbox Lua module Cyrill Gorcunov
2020-10-08 22:35 ` Vladislav Shpilevoy
2020-10-09 6:57 ` Cyrill Gorcunov
2020-10-09 21:31 ` Vladislav Shpilevoy
2020-10-11 21:34 ` Cyrill Gorcunov
2020-10-09 21:46 ` Vladislav Shpilevoy
2020-10-11 21:58 ` Cyrill Gorcunov
2020-10-08 21:36 ` [Tarantool-patches] [PATCH v5 6/6] test: box/cfunc -- add simple module test Cyrill Gorcunov
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=20201008213608.1022476-3-gorcunov@gmail.com \
--to=gorcunov@gmail.com \
--cc=tarantool-patches@dev.tarantool.org \
--cc=v.shpilevoy@tarantool.org \
--subject='Re: [Tarantool-patches] [PATCH v5 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