Skip to content
Snippets Groups Projects
Commit 5a2f552e authored by Roman Tsisyk's avatar Roman Tsisyk
Browse files

Encapsulate dynamic function calls to func.hc

Needed for #910
parent cf212c9f
No related branches found
No related tags found
No related merge requests found
...@@ -69,23 +69,22 @@ access_check_func(const char *name, uint32_t name_len) ...@@ -69,23 +69,22 @@ access_check_func(const char *name, uint32_t name_len)
} }
static int static int
func_call(struct func *func, struct call_request *request, struct obuf *out) box_c_call(struct func *func, struct call_request *request, struct obuf *out)
{ {
assert(func != NULL && func->def->language == FUNC_LANGUAGE_C); assert(func != NULL && func->def->language == FUNC_LANGUAGE_C);
if (func->func == NULL)
func_load(func);
/* Create a call context */ /* Create a call context */
struct port port; struct port port;
port_create(&port); port_create(&port);
auto port_guard = make_scoped_guard([&](){ port_destroy(&port); }); auto port_guard = make_scoped_guard([&](){ port_destroy(&port); });
box_function_ctx_t ctx = { request, &port }; box_function_ctx_t ctx = { &port };
/* Clear all previous errors */ /* Clear all previous errors */
diag_clear(&fiber()->diag); diag_clear(&fiber()->diag);
assert(!in_txn()); /* transaction is not started */ assert(!in_txn()); /* transaction is not started */
/* Call function from the shared library */ /* Call function from the shared library */
int rc = func->func(&ctx, request->args, request->args_end); int rc = func_call(func, &ctx, request->args, request->args_end);
if (rc != 0) { if (rc != 0) {
if (diag_last_error(&fiber()->diag) == NULL) { if (diag_last_error(&fiber()->diag) == NULL) {
/* Stored procedure forget to set diag */ /* Stored procedure forget to set diag */
...@@ -171,7 +170,7 @@ box_process_call(struct call_request *request, struct obuf *out) ...@@ -171,7 +170,7 @@ box_process_call(struct call_request *request, struct obuf *out)
int rc; int rc;
if (func && func->def->language == FUNC_LANGUAGE_C) { if (func && func->def->language == FUNC_LANGUAGE_C) {
rc = func_call(func, request, out); rc = box_c_call(func, request, out);
} else { } else {
rc = box_lua_call(request, out); rc = box_lua_call(request, out);
} }
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
struct obuf; struct obuf;
struct box_function_ctx { struct box_function_ctx {
struct call_request *request;
struct port *port; struct port *port;
}; };
......
...@@ -171,29 +171,50 @@ func_unload(struct func *func) ...@@ -171,29 +171,50 @@ func_unload(struct func *func)
func->func = NULL; func->func = NULL;
} }
void /**
* Resolve func->func (find the respective DLL and fetch the
* symbol from it).
*/
static int
func_load(struct func *func) func_load(struct func *func)
{ {
func_unload(func); assert(func->func == NULL);
struct func_name name; struct func_name name;
func_split_name(func->def->name, &name); func_split_name(func->def->name, &name);
char path[PATH_MAX]; char path[PATH_MAX];
if (module_find(name.package, name.package_end, path, sizeof(path))) if (module_find(name.package, name.package_end, path, sizeof(path)))
diag_raise(); return -1;
func->dlhandle = dlopen(path, RTLD_NOW | RTLD_LOCAL); func->dlhandle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (func->dlhandle == NULL) { if (func->dlhandle == NULL) {
int package_len = (int) (name.package_end - name.package_end); int package_len = (int) (name.package_end - name.package_end);
tnt_raise(LoggedError, ER_LOAD_MODULE, package_len, diag_set(ClientError, ER_LOAD_MODULE, package_len,
name.package, dlerror()); name.package, dlerror());
diag_log();
return -1;
} }
func->func = (box_function_f) dlsym(func->dlhandle, name.sym); func->func = (box_function_f) dlsym(func->dlhandle, name.sym);
if (func->func == NULL) { if (func->func == NULL) {
tnt_raise(LoggedError, ER_LOAD_FUNCTION, func->def->name, diag_set(ClientError, ER_LOAD_FUNCTION, func->def->name,
dlerror()); dlerror());
diag_log();
return -1;
} }
return 0;
}
int
func_call(struct func *func, box_function_ctx_t *ctx, const char *args,
const char *args_end)
{
if (func->func == NULL) {
if (func_load(func) != 0)
return -1;
}
return func->func(ctx, args, args_end);
} }
void void
......
...@@ -74,11 +74,11 @@ void ...@@ -74,11 +74,11 @@ void
func_delete(struct func *func); func_delete(struct func *func);
/** /**
* Resolve func->func (find the respective DLL and fetch the * Call stored C function using @a args.
* symbol from it).
*/ */
void int
func_load(struct func *func); func_call(struct func *func, box_function_ctx_t *ctx, const char *args,
const char *args_end);
#endif /* defined(__cplusplus) */ #endif /* defined(__cplusplus) */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment