From: Georgy Kirichenko <georgy@tarantool.org> To: tarantool-patches@freelists.org Cc: Georgy Kirichenko <georgy@tarantool.org> Subject: [tarantool-patches] [PATCH v3 3/4] Use fiber lua state for triggers if possible Date: Wed, 31 Oct 2018 13:49:12 +0300 [thread overview] Message-ID: <831cede7b67260e3a8e9f78b275b7e8c4ffbdcdc.1540982711.git.georgy@tarantool.org> (raw) In-Reply-To: <cover.1540982711.git.georgy@tarantool.org> Lua trigger invocation reuses a fiber lua state if exists instead of creating of new one for each new invocation. This is needed for a lua stack reconstruction during backtracing. Relates: #3538 --- src/box/lua/space.cc | 12 ++++++------ src/fiber.h | 32 ++++++++++++++------------------ src/lua/trigger.c | 19 ++++++++++++++----- src/lua/trigger.h | 2 +- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index 25b7e36da..df698810b 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -73,20 +73,20 @@ lbox_push_txn_stmt(struct lua_State *L, void *event) } static int -lbox_pop_txn_stmt(struct lua_State *L, void *event) +lbox_pop_txn_stmt(struct lua_State *L, int nret, void *event) { struct txn_stmt *stmt = txn_current_stmt((struct txn *) event); - if (lua_gettop(L) < 1) { + if (nret < 1) { /* No return value - nothing to do. */ return 0; } - - struct tuple *result = luaT_istuple(L, 1); - if (result == NULL && !lua_isnil(L, 1) && !luaL_isnull(L, 1)) { + int top = lua_gettop(L) - nret + 1; + struct tuple *result = luaT_istuple(L, top); + if (result == NULL && !lua_isnil(L, top) && !luaL_isnull(L, top)) { /* Invalid return value - raise error. */ diag_set(ClientError, ER_BEFORE_REPLACE_RET, - lua_typename(L, lua_type(L, 1))); + lua_typename(L, lua_type(L, top))); return -1; } diff --git a/src/fiber.h b/src/fiber.h index bb5343fdc..d4ed1193a 100644 --- a/src/fiber.h +++ b/src/fiber.h @@ -398,24 +398,20 @@ struct fiber { struct session *session; struct credentials *credentials; struct txn *txn; - union { - /** - * Fields used by a fiber created in Lua: - * Lua stack and the optional - * fiber.storage Lua reference. - */ - struct { - struct lua_State *stack; - int ref; - } lua; - /** - * Fields used by a fiber created to - * process an iproto request. - */ - struct { - uint64_t sync; - } net; - }; + /** + * Lua stack and the optional + * fiber.storage Lua reference. + */ + struct { + struct lua_State *stack; + int ref; + } lua; + /** + * Iproto sync. + */ + struct { + uint64_t sync; + } net; } storage; /** An object to wait for incoming message or a reader. */ struct ipc_wait_pad *wait_pad; diff --git a/src/lua/trigger.c b/src/lua/trigger.c index c758e47ea..2c2ede212 100644 --- a/src/lua/trigger.c +++ b/src/lua/trigger.c @@ -80,16 +80,25 @@ lbox_trigger_run(struct trigger *ptr, void *event) * invocation, and in future we plan to hack into Lua * C API to fix this. */ - struct lua_State *L = lua_newthread(tarantool_L); - int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); + struct lua_State *L; + int coro_ref; + if (fiber()->storage.lua.stack == NULL) { + L = lua_newthread(tarantool_L); + coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); + } else { + L = fiber()->storage.lua.stack; + coro_ref = LUA_REFNIL; + } + int top = lua_gettop(L); lua_rawgeti(L, LUA_REGISTRYINDEX, trigger->ref); - int top = trigger->push_event(L, event); - if (luaT_call(L, top, LUA_MULTRET)) { + int nargs = trigger->push_event(L, event); + if (luaT_call(L, nargs, LUA_MULTRET)) { luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); diag_raise(); } + int nret = lua_gettop(L) - top; if (trigger->pop_event != NULL && - trigger->pop_event(L, event) != 0) { + trigger->pop_event(L, nret, event) != 0) { luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); diag_raise(); } diff --git a/src/lua/trigger.h b/src/lua/trigger.h index 8901f5dea..1d1dcce35 100644 --- a/src/lua/trigger.h +++ b/src/lua/trigger.h @@ -52,7 +52,7 @@ typedef int * error will be raised for the caller. */ typedef int -(*lbox_pop_event_f)(struct lua_State *L, void *event); +(*lbox_pop_event_f)(struct lua_State *L, int nret, void *event); /** * Create a Lua trigger, replace an existing one, -- 2.19.1
next prev parent reply other threads:[~2018-10-31 10:49 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-10-31 10:49 [tarantool-patches] [PATCH v3 0/4] Dump lua frames for a fiber traceback Georgy Kirichenko 2018-10-31 10:49 ` [tarantool-patches] [PATCH v3 1/4] fiber: do not inline coro unwind function Georgy Kirichenko 2018-10-31 10:49 ` [tarantool-patches] [PATCH v3 2/4] Proper unwind for currently executing fiber Georgy Kirichenko 2018-10-31 10:49 ` Georgy Kirichenko [this message] 2018-10-31 10:49 ` [tarantool-patches] [PATCH v3 4/4] Show names of Lua functions in backtraces Georgy Kirichenko 2018-11-01 12:45 ` [tarantool-patches] [PATCH v3 0/4] Dump lua frames for a fiber traceback Vladimir Davydov
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=831cede7b67260e3a8e9f78b275b7e8c4ffbdcdc.1540982711.git.georgy@tarantool.org \ --to=georgy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH v3 3/4] Use fiber lua state for triggers if possible' \ /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