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