diff --git a/src/box/call.cc b/src/box/call.cc index 3e07ac7dad02da71a71a279a534894d0ed7d51e8..c8fbf3d33c05c100722ef07a67859d4d37f13944 100644 --- a/src/box/call.cc +++ b/src/box/call.cc @@ -69,23 +69,22 @@ access_check_func(const char *name, uint32_t name_len) } 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); - if (func->func == NULL) - func_load(func); /* Create a call context */ struct port port; port_create(&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 */ diag_clear(&fiber()->diag); assert(!in_txn()); /* transaction is not started */ + /* 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 (diag_last_error(&fiber()->diag) == NULL) { /* Stored procedure forget to set diag */ @@ -171,7 +170,7 @@ box_process_call(struct call_request *request, struct obuf *out) int rc; if (func && func->def->language == FUNC_LANGUAGE_C) { - rc = func_call(func, request, out); + rc = box_c_call(func, request, out); } else { rc = box_lua_call(request, out); } diff --git a/src/box/call.h b/src/box/call.h index 826ca4d5fe22d1d4646822d693e2da0a2c5fa5f3..b44a696f1c1d235f219d4210b9ebfbdbfccb0278 100644 --- a/src/box/call.h +++ b/src/box/call.h @@ -36,7 +36,6 @@ struct obuf; struct box_function_ctx { - struct call_request *request; struct port *port; }; diff --git a/src/box/func.cc b/src/box/func.cc index c37d9be47c860f36440d051bc2696ab017a44313..da456ab1bf3eccb800a3b786a5ba9e8424e03337 100644 --- a/src/box/func.cc +++ b/src/box/func.cc @@ -171,29 +171,50 @@ func_unload(struct func *func) 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_unload(func); + assert(func->func == NULL); struct func_name name; func_split_name(func->def->name, &name); char path[PATH_MAX]; if (module_find(name.package, name.package_end, path, sizeof(path))) - diag_raise(); + return -1; func->dlhandle = dlopen(path, RTLD_NOW | RTLD_LOCAL); if (func->dlhandle == NULL) { 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()); + diag_log(); + return -1; } func->func = (box_function_f) dlsym(func->dlhandle, name.sym); if (func->func == NULL) { - tnt_raise(LoggedError, ER_LOAD_FUNCTION, func->def->name, + diag_set(ClientError, ER_LOAD_FUNCTION, func->def->name, 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 diff --git a/src/box/func.h b/src/box/func.h index c29b964ea528215f4d377640e6736b8ecd569ddf..d5a51a354b2f81afd79842e10dda4e88da411d97 100644 --- a/src/box/func.h +++ b/src/box/func.h @@ -74,11 +74,11 @@ void func_delete(struct func *func); /** - * Resolve func->func (find the respective DLL and fetch the - * symbol from it). + * Call stored C function using @a args. */ -void -func_load(struct func *func); +int +func_call(struct func *func, box_function_ctx_t *ctx, const char *args, + const char *args_end); #endif /* defined(__cplusplus) */