diff --git a/src/box/func.h b/src/box/func.h index 30e748dbbeca0f1e8436e8b3f1628328ab5941e5..a8a6932689ab58fe866fa5dfcc929f99a908b1f3 100644 --- a/src/box/func.h +++ b/src/box/func.h @@ -90,7 +90,12 @@ void func_delete(struct func *func); /** - * Call function with arguments represented with given args. + * Call function @a func with arguments @a args, put return value to @a ret. + * Return 0 on success and nonzero on failure. + * The port @a args must be initialized by the caller while @a ret is + * initialized by func_call, and only in case of success. + * Thus the caller must not initialize @a ret by himself and must destroy it + * if and only if func_call returns 0; */ int func_call(struct func *func, struct port *args, struct port *ret); diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index defb4cb9d765823453dbc8351e3ef80646ac3d2a..4a01d8d2f2d4c0cfc1fe5153ad1f25e30f5bb9bd 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -83,6 +83,11 @@ ffi.cdef[[ box_txn_savepoint_t * box_txn_savepoint(); + struct port { + const struct port_vtab *vtab; + char pad[60]; + }; + struct port_c_entry { struct port_c_entry *next; union { @@ -1496,7 +1501,8 @@ local iterator_gen_luac = function(param, state) -- luacheck: no unused args end -- global struct port instance to use by select()/get() -local port_c = ffi.new('struct port_c') +local port = ffi.new('struct port') +local port_c = ffi.cast('struct port_c *', port) -- Helper function to check space:method() usage local function check_space_arg(space, method) @@ -2043,7 +2049,6 @@ base_index_mt.select_ffi = function(index, key, opts) local key, key_end = tuple_encode(ibuf, key) local iterator, offset, limit = check_select_opts(opts, key + 1 >= key_end) - local port = ffi.cast('struct port *', port_c) local nok = builtin.box_select(index.space_id, index.id, iterator, offset, limit, key, key_end, port) ~= 0 cord_ibuf_put(ibuf) diff --git a/src/box/port.h b/src/box/port.h index 43d0f9deb7d8d21197777917c5a1674a901385aa..d298e015ebb5598889b204be8416144ca732e9e0 100644 --- a/src/box/port.h +++ b/src/box/port.h @@ -124,6 +124,8 @@ struct port_c_entry { /** * C port is used by C functions from the public API. They can * return tuples and arbitrary MessagePack. + * Warning: this structure is exposed in FFI, so any change in it must be + * replicated if FFI cdef, see schema.lua. */ struct port_c { const struct port_vtab *vtab; diff --git a/src/lib/core/port.c b/src/lib/core/port.c index 03694b4668f3b6cb76a2791a1ddf9f7a095412b8..8d5dadbf4cc18cf38baee5bdeaf412eecbb15a8f 100644 --- a/src/lib/core/port.c +++ b/src/lib/core/port.c @@ -29,9 +29,11 @@ * SUCH DAMAGE. */ #include "port.h" +#include "trivia/util.h" void port_destroy(struct port *port) { port->vtab->destroy(port); + TRASH(port); } diff --git a/src/lib/core/port.h b/src/lib/core/port.h index 5c51f76e1141468707609ede3dc026fcec75661e..2f884270980b0c2193f0454614f791943186ba14 100644 --- a/src/lib/core/port.h +++ b/src/lib/core/port.h @@ -114,6 +114,8 @@ struct port_vtab { /** * Abstract port instance. It is supposed to be converted to * a concrete port realization, e.g. port_c. + * Warning: this structure is exposed in FFI, so any change in it must be + * replicated if FFI cdef, see schema.lua. */ struct port { /** Virtual method table. */