Tarantool development patches archive
 help / color / mirror / Atom feed
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

  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