Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall
@ 2019-10-18  9:29 Ilya Kosarev
  2019-10-18 12:14 ` Igor Munkin
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Ilya Kosarev @ 2019-10-18  9:29 UTC (permalink / raw)
  To: tarantool-patches; +Cc: tarantool-patches

Wrap throwing lua_newthread in luaT_newthread using luaT_cpcall
to process arising error properly.

Closes #4556
---
https://github.com/tarantool/tarantool/tree/i.kosarev/gh-4556-wrap-lua-newthread
https://github.com/tarantool/tarantool/issues/4556

Changes in v2:
- introduced luaT_newthread instead of repeated slocs
- renamed luaL_pushthread to luaT_pushthread due to namespaces agreement

Changes in v3:
- remove extra luaT_pushthread function
- renamed lua_newthread_wrapper to luaT_newthread_wrapper due to namespaces agreement

 src/box/lua/call.c            | 12 +++++++++---
 src/lua/fiber.c               |  4 +++-
 src/lua/trigger.c             | 12 ++++--------
 src/lua/utils.h               | 30 ++++++++++++++++++++++++++++++
 third_party/lua-yaml/lyaml.cc |  5 ++++-
 5 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/src/box/lua/call.c b/src/box/lua/call.c
index 631003c84..51cad286a 100644
--- a/src/box/lua/call.c
+++ b/src/box/lua/call.c
@@ -527,7 +527,9 @@ static inline int
 box_process_lua(lua_CFunction handler, struct execute_lua_ctx *ctx,
 		struct port *ret)
 {
-	lua_State *L = lua_newthread(tarantool_L);
+	lua_State *L = luaT_newthread(tarantool_L);
+	if (L == NULL)
+		return -1;
 	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
 	port_lua_create(ret, L);
 	((struct port_lua *) ret)->ref = coro_ref;
@@ -654,7 +656,9 @@ func_persistent_lua_load(struct func_lua *func)
 	 * an arbitrary user-defined code
 	 * (e.g. body = 'fiber.yield()').
 	 */
-	struct lua_State *coro_L = lua_newthread(tarantool_L);
+	lua_State *coro_L = luaT_newthread(tarantool_L);
+	if (coro_L == NULL)
+		return -1;
 	if (!func->base.def->is_sandboxed) {
 		/*
 		 * Keep the original env to apply to a non-sandboxed
@@ -811,7 +815,9 @@ lbox_func_call(struct lua_State *L)
 	 * before the function call to pass it into the
 	 * pcall-sandboxed tarantool_L handler.
 	 */
-	lua_State *args_L = lua_newthread(tarantool_L);
+	lua_State *args_L = luaT_newthread(tarantool_L);
+	if (args_L == NULL)
+		return luaT_error(L);
 	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
 	lua_xmove(L, args_L, lua_gettop(L) - 1);
 	struct port args;
diff --git a/src/lua/fiber.c b/src/lua/fiber.c
index 336be60a2..124908a05 100644
--- a/src/lua/fiber.c
+++ b/src/lua/fiber.c
@@ -388,7 +388,9 @@ lua_fiber_run_f(MAYBE_UNUSED va_list ap)
 static struct fiber *
 fiber_create(struct lua_State *L)
 {
-	struct lua_State *child_L = lua_newthread(L);
+	lua_State *child_L = luaT_newthread(L);
+	if (child_L == NULL)
+		luaT_error(L);
 	int coro_ref = luaL_ref(L, LUA_REGISTRYINDEX);
 
 	struct fiber *f = fiber_new("lua", lua_fiber_run_f);
diff --git a/src/lua/trigger.c b/src/lua/trigger.c
index 4803e85c5..6df048a8d 100644
--- a/src/lua/trigger.c
+++ b/src/lua/trigger.c
@@ -73,17 +73,13 @@ lbox_trigger_run(struct trigger *ptr, void *event)
 	 * trigger yields, so when it's time to clean
 	 * up the coro, we wouldn't know which stack position
 	 * it is on.
-	 *
-	 * XXX: lua_newthread() may throw if out of memory,
-	 * this needs to be wrapped with lua_pcall() as well.
-	 * Don't, since it's a stupid overhead on every trigger
-	 * invocation, and in future we plan to hack into Lua
-	 * C API to fix this.
 	 */
-	struct lua_State *L;
+	lua_State *L;
 	int coro_ref;
 	if (fiber()->storage.lua.stack == NULL) {
-		L = lua_newthread(tarantool_L);
+		L = luaT_newthread(tarantool_L);
+		if (L == NULL)
+			diag_raise();
 		coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
 	} else {
 		L = fiber()->storage.lua.stack;
diff --git a/src/lua/utils.h b/src/lua/utils.h
index f8c34545a..d9fb0704f 100644
--- a/src/lua/utils.h
+++ b/src/lua/utils.h
@@ -591,6 +591,36 @@ luaL_checkfinite(struct lua_State *L, struct luaL_serializer *cfg,
 		luaL_error(L, "number must not be NaN or Inf");
 }
 
+/**
+ * @brief A wrapper for lua_newthread() to pass it into luaT_cpcall
+ * @param L is a Lua State
+ * @sa lua_newthread()
+ */
+static inline int
+luaT_newthread_wrapper(lua_State *L)
+{
+	*(lua_State **)lua_touserdata(L, 1) = lua_newthread(L);
+	return 0;
+}
+
+/**
+ * @brief Safe wrapper for lua_newthread()
+ * @param L is a Lua State
+ * @sa lua_newthread()
+ */
+static inline lua_State *
+luaT_newthread(lua_State *L)
+{
+	lua_State *L1 = NULL;
+	if (luaT_cpcall(L, luaT_newthread_wrapper, &L1) != 0) {
+		return NULL;
+	}
+	assert(L1 != NULL);
+	setthreadV(L, L->top, L1);
+	incr_top(L);
+	return L1;
+}
+
 /**
  * Check if a value on @a L stack by index @a idx is an ibuf
  * object. Both 'struct ibuf' and 'struct ibuf *' are accepted.
diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
index 7485341fa..af4f2f5d5 100644
--- a/third_party/lua-yaml/lyaml.cc
+++ b/third_party/lua-yaml/lyaml.cc
@@ -789,7 +789,10 @@ lua_yaml_encode(lua_State *L, struct luaL_serializer *serializer,
    dumper.cfg = serializer;
    dumper.error = 0;
    /* create thread to use for YAML buffer */
-   dumper.outputL = lua_newthread(L);
+   dumper.outputL = luaT_newthread(L);
+   if (dumper.outputL == NULL) {
+      return luaL_error(L, OOM_ERRMSG);
+   }
    luaL_buffinit(dumper.outputL, &dumper.yamlbuf);
 
    if (!yaml_emitter_initialize(&dumper.emitter))
-- 
2.17.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall
  2019-10-18  9:29 [Tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall Ilya Kosarev
@ 2019-10-18 12:14 ` Igor Munkin
  2019-10-18 14:08 ` [Tarantool-patches] [tarantool-patches] " Sergey Ostanevich
  2019-10-21  7:51 ` Kirill Yukhin
  2 siblings, 0 replies; 4+ messages in thread
From: Igor Munkin @ 2019-10-18 12:14 UTC (permalink / raw)
  To: Ilya Kosarev; +Cc: tarantool-patches, tarantool-patches

Ilya,

Thanks, LGTM.

On 18.10.19, Ilya Kosarev wrote:
> Wrap throwing lua_newthread in luaT_newthread using luaT_cpcall
> to process arising error properly.
> 
> Closes #4556
> ---
> https://github.com/tarantool/tarantool/tree/i.kosarev/gh-4556-wrap-lua-newthread
> https://github.com/tarantool/tarantool/issues/4556
> 
> Changes in v2:
> - introduced luaT_newthread instead of repeated slocs
> - renamed luaL_pushthread to luaT_pushthread due to namespaces agreement
> 
> Changes in v3:
> - remove extra luaT_pushthread function
> - renamed lua_newthread_wrapper to luaT_newthread_wrapper due to namespaces agreement
> 
>  src/box/lua/call.c            | 12 +++++++++---
>  src/lua/fiber.c               |  4 +++-
>  src/lua/trigger.c             | 12 ++++--------
>  src/lua/utils.h               | 30 ++++++++++++++++++++++++++++++
>  third_party/lua-yaml/lyaml.cc |  5 ++++-
>  5 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/src/box/lua/call.c b/src/box/lua/call.c
> index 631003c84..51cad286a 100644
> --- a/src/box/lua/call.c
> +++ b/src/box/lua/call.c
> @@ -527,7 +527,9 @@ static inline int
>  box_process_lua(lua_CFunction handler, struct execute_lua_ctx *ctx,
>  		struct port *ret)
>  {
> -	lua_State *L = lua_newthread(tarantool_L);
> +	lua_State *L = luaT_newthread(tarantool_L);
> +	if (L == NULL)
> +		return -1;
>  	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
>  	port_lua_create(ret, L);
>  	((struct port_lua *) ret)->ref = coro_ref;
> @@ -654,7 +656,9 @@ func_persistent_lua_load(struct func_lua *func)
>  	 * an arbitrary user-defined code
>  	 * (e.g. body = 'fiber.yield()').
>  	 */
> -	struct lua_State *coro_L = lua_newthread(tarantool_L);
> +	lua_State *coro_L = luaT_newthread(tarantool_L);
> +	if (coro_L == NULL)
> +		return -1;
>  	if (!func->base.def->is_sandboxed) {
>  		/*
>  		 * Keep the original env to apply to a non-sandboxed
> @@ -811,7 +815,9 @@ lbox_func_call(struct lua_State *L)
>  	 * before the function call to pass it into the
>  	 * pcall-sandboxed tarantool_L handler.
>  	 */
> -	lua_State *args_L = lua_newthread(tarantool_L);
> +	lua_State *args_L = luaT_newthread(tarantool_L);
> +	if (args_L == NULL)
> +		return luaT_error(L);
>  	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
>  	lua_xmove(L, args_L, lua_gettop(L) - 1);
>  	struct port args;
> diff --git a/src/lua/fiber.c b/src/lua/fiber.c
> index 336be60a2..124908a05 100644
> --- a/src/lua/fiber.c
> +++ b/src/lua/fiber.c
> @@ -388,7 +388,9 @@ lua_fiber_run_f(MAYBE_UNUSED va_list ap)
>  static struct fiber *
>  fiber_create(struct lua_State *L)
>  {
> -	struct lua_State *child_L = lua_newthread(L);
> +	lua_State *child_L = luaT_newthread(L);
> +	if (child_L == NULL)
> +		luaT_error(L);
>  	int coro_ref = luaL_ref(L, LUA_REGISTRYINDEX);
>  
>  	struct fiber *f = fiber_new("lua", lua_fiber_run_f);
> diff --git a/src/lua/trigger.c b/src/lua/trigger.c
> index 4803e85c5..6df048a8d 100644
> --- a/src/lua/trigger.c
> +++ b/src/lua/trigger.c
> @@ -73,17 +73,13 @@ lbox_trigger_run(struct trigger *ptr, void *event)
>  	 * trigger yields, so when it's time to clean
>  	 * up the coro, we wouldn't know which stack position
>  	 * it is on.
> -	 *
> -	 * XXX: lua_newthread() may throw if out of memory,
> -	 * this needs to be wrapped with lua_pcall() as well.
> -	 * Don't, since it's a stupid overhead on every trigger
> -	 * invocation, and in future we plan to hack into Lua
> -	 * C API to fix this.
>  	 */
> -	struct lua_State *L;
> +	lua_State *L;
>  	int coro_ref;
>  	if (fiber()->storage.lua.stack == NULL) {
> -		L = lua_newthread(tarantool_L);
> +		L = luaT_newthread(tarantool_L);
> +		if (L == NULL)
> +			diag_raise();
>  		coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
>  	} else {
>  		L = fiber()->storage.lua.stack;
> diff --git a/src/lua/utils.h b/src/lua/utils.h
> index f8c34545a..d9fb0704f 100644
> --- a/src/lua/utils.h
> +++ b/src/lua/utils.h
> @@ -591,6 +591,36 @@ luaL_checkfinite(struct lua_State *L, struct luaL_serializer *cfg,
>  		luaL_error(L, "number must not be NaN or Inf");
>  }
>  
> +/**
> + * @brief A wrapper for lua_newthread() to pass it into luaT_cpcall
> + * @param L is a Lua State
> + * @sa lua_newthread()
> + */
> +static inline int
> +luaT_newthread_wrapper(lua_State *L)
> +{
> +	*(lua_State **)lua_touserdata(L, 1) = lua_newthread(L);
> +	return 0;
> +}
> +
> +/**
> + * @brief Safe wrapper for lua_newthread()
> + * @param L is a Lua State
> + * @sa lua_newthread()
> + */
> +static inline lua_State *
> +luaT_newthread(lua_State *L)
> +{
> +	lua_State *L1 = NULL;
> +	if (luaT_cpcall(L, luaT_newthread_wrapper, &L1) != 0) {
> +		return NULL;
> +	}
> +	assert(L1 != NULL);
> +	setthreadV(L, L->top, L1);
> +	incr_top(L);
> +	return L1;
> +}
> +
>  /**
>   * Check if a value on @a L stack by index @a idx is an ibuf
>   * object. Both 'struct ibuf' and 'struct ibuf *' are accepted.
> diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
> index 7485341fa..af4f2f5d5 100644
> --- a/third_party/lua-yaml/lyaml.cc
> +++ b/third_party/lua-yaml/lyaml.cc
> @@ -789,7 +789,10 @@ lua_yaml_encode(lua_State *L, struct luaL_serializer *serializer,
>     dumper.cfg = serializer;
>     dumper.error = 0;
>     /* create thread to use for YAML buffer */
> -   dumper.outputL = lua_newthread(L);
> +   dumper.outputL = luaT_newthread(L);
> +   if (dumper.outputL == NULL) {
> +      return luaL_error(L, OOM_ERRMSG);
> +   }
>     luaL_buffinit(dumper.outputL, &dumper.yamlbuf);
>  
>     if (!yaml_emitter_initialize(&dumper.emitter))
> -- 
> 2.17.1
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall
  2019-10-18  9:29 [Tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall Ilya Kosarev
  2019-10-18 12:14 ` Igor Munkin
@ 2019-10-18 14:08 ` Sergey Ostanevich
  2019-10-21  7:51 ` Kirill Yukhin
  2 siblings, 0 replies; 4+ messages in thread
From: Sergey Ostanevich @ 2019-10-18 14:08 UTC (permalink / raw)
  To: tarantool-patches; +Cc: tarantool-patches

Hi!

LGTM, thank you!

Sergos


On 18 Oct 12:29, Ilya Kosarev wrote:
> Wrap throwing lua_newthread in luaT_newthread using luaT_cpcall
> to process arising error properly.
> 
> Closes #4556
> ---
> https://github.com/tarantool/tarantool/tree/i.kosarev/gh-4556-wrap-lua-newthread
> https://github.com/tarantool/tarantool/issues/4556
> 
> Changes in v2:
> - introduced luaT_newthread instead of repeated slocs
> - renamed luaL_pushthread to luaT_pushthread due to namespaces agreement
> 
> Changes in v3:
> - remove extra luaT_pushthread function
> - renamed lua_newthread_wrapper to luaT_newthread_wrapper due to namespaces agreement
> 
>  src/box/lua/call.c            | 12 +++++++++---
>  src/lua/fiber.c               |  4 +++-
>  src/lua/trigger.c             | 12 ++++--------
>  src/lua/utils.h               | 30 ++++++++++++++++++++++++++++++
>  third_party/lua-yaml/lyaml.cc |  5 ++++-
>  5 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/src/box/lua/call.c b/src/box/lua/call.c
> index 631003c84..51cad286a 100644
> --- a/src/box/lua/call.c
> +++ b/src/box/lua/call.c
> @@ -527,7 +527,9 @@ static inline int
>  box_process_lua(lua_CFunction handler, struct execute_lua_ctx *ctx,
>  		struct port *ret)
>  {
> -	lua_State *L = lua_newthread(tarantool_L);
> +	lua_State *L = luaT_newthread(tarantool_L);
> +	if (L == NULL)
> +		return -1;
>  	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
>  	port_lua_create(ret, L);
>  	((struct port_lua *) ret)->ref = coro_ref;
> @@ -654,7 +656,9 @@ func_persistent_lua_load(struct func_lua *func)
>  	 * an arbitrary user-defined code
>  	 * (e.g. body = 'fiber.yield()').
>  	 */
> -	struct lua_State *coro_L = lua_newthread(tarantool_L);
> +	lua_State *coro_L = luaT_newthread(tarantool_L);
> +	if (coro_L == NULL)
> +		return -1;
>  	if (!func->base.def->is_sandboxed) {
>  		/*
>  		 * Keep the original env to apply to a non-sandboxed
> @@ -811,7 +815,9 @@ lbox_func_call(struct lua_State *L)
>  	 * before the function call to pass it into the
>  	 * pcall-sandboxed tarantool_L handler.
>  	 */
> -	lua_State *args_L = lua_newthread(tarantool_L);
> +	lua_State *args_L = luaT_newthread(tarantool_L);
> +	if (args_L == NULL)
> +		return luaT_error(L);
>  	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
>  	lua_xmove(L, args_L, lua_gettop(L) - 1);
>  	struct port args;
> diff --git a/src/lua/fiber.c b/src/lua/fiber.c
> index 336be60a2..124908a05 100644
> --- a/src/lua/fiber.c
> +++ b/src/lua/fiber.c
> @@ -388,7 +388,9 @@ lua_fiber_run_f(MAYBE_UNUSED va_list ap)
>  static struct fiber *
>  fiber_create(struct lua_State *L)
>  {
> -	struct lua_State *child_L = lua_newthread(L);
> +	lua_State *child_L = luaT_newthread(L);
> +	if (child_L == NULL)
> +		luaT_error(L);
>  	int coro_ref = luaL_ref(L, LUA_REGISTRYINDEX);
>  
>  	struct fiber *f = fiber_new("lua", lua_fiber_run_f);
> diff --git a/src/lua/trigger.c b/src/lua/trigger.c
> index 4803e85c5..6df048a8d 100644
> --- a/src/lua/trigger.c
> +++ b/src/lua/trigger.c
> @@ -73,17 +73,13 @@ lbox_trigger_run(struct trigger *ptr, void *event)
>  	 * trigger yields, so when it's time to clean
>  	 * up the coro, we wouldn't know which stack position
>  	 * it is on.
> -	 *
> -	 * XXX: lua_newthread() may throw if out of memory,
> -	 * this needs to be wrapped with lua_pcall() as well.
> -	 * Don't, since it's a stupid overhead on every trigger
> -	 * invocation, and in future we plan to hack into Lua
> -	 * C API to fix this.
>  	 */
> -	struct lua_State *L;
> +	lua_State *L;
>  	int coro_ref;
>  	if (fiber()->storage.lua.stack == NULL) {
> -		L = lua_newthread(tarantool_L);
> +		L = luaT_newthread(tarantool_L);
> +		if (L == NULL)
> +			diag_raise();
>  		coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
>  	} else {
>  		L = fiber()->storage.lua.stack;
> diff --git a/src/lua/utils.h b/src/lua/utils.h
> index f8c34545a..d9fb0704f 100644
> --- a/src/lua/utils.h
> +++ b/src/lua/utils.h
> @@ -591,6 +591,36 @@ luaL_checkfinite(struct lua_State *L, struct luaL_serializer *cfg,
>  		luaL_error(L, "number must not be NaN or Inf");
>  }
>  
> +/**
> + * @brief A wrapper for lua_newthread() to pass it into luaT_cpcall
> + * @param L is a Lua State
> + * @sa lua_newthread()
> + */
> +static inline int
> +luaT_newthread_wrapper(lua_State *L)
> +{
> +	*(lua_State **)lua_touserdata(L, 1) = lua_newthread(L);
> +	return 0;
> +}
> +
> +/**
> + * @brief Safe wrapper for lua_newthread()
> + * @param L is a Lua State
> + * @sa lua_newthread()
> + */
> +static inline lua_State *
> +luaT_newthread(lua_State *L)
> +{
> +	lua_State *L1 = NULL;
> +	if (luaT_cpcall(L, luaT_newthread_wrapper, &L1) != 0) {
> +		return NULL;
> +	}
> +	assert(L1 != NULL);
> +	setthreadV(L, L->top, L1);
> +	incr_top(L);
> +	return L1;
> +}
> +
>  /**
>   * Check if a value on @a L stack by index @a idx is an ibuf
>   * object. Both 'struct ibuf' and 'struct ibuf *' are accepted.
> diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
> index 7485341fa..af4f2f5d5 100644
> --- a/third_party/lua-yaml/lyaml.cc
> +++ b/third_party/lua-yaml/lyaml.cc
> @@ -789,7 +789,10 @@ lua_yaml_encode(lua_State *L, struct luaL_serializer *serializer,
>     dumper.cfg = serializer;
>     dumper.error = 0;
>     /* create thread to use for YAML buffer */
> -   dumper.outputL = lua_newthread(L);
> +   dumper.outputL = luaT_newthread(L);
> +   if (dumper.outputL == NULL) {
> +      return luaL_error(L, OOM_ERRMSG);
> +   }
>     luaL_buffinit(dumper.outputL, &dumper.yamlbuf);
>  
>     if (!yaml_emitter_initialize(&dumper.emitter))
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall
  2019-10-18  9:29 [Tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall Ilya Kosarev
  2019-10-18 12:14 ` Igor Munkin
  2019-10-18 14:08 ` [Tarantool-patches] [tarantool-patches] " Sergey Ostanevich
@ 2019-10-21  7:51 ` Kirill Yukhin
  2 siblings, 0 replies; 4+ messages in thread
From: Kirill Yukhin @ 2019-10-21  7:51 UTC (permalink / raw)
  To: tarantool-patches; +Cc: tarantool-patches

Hello,

On 18 окт 12:29, Ilya Kosarev wrote:
> Wrap throwing lua_newthread in luaT_newthread using luaT_cpcall
> to process arising error properly.
> 
> Closes #4556

I've checked your patch into 1.10, 2.1, 2.2 and master.

--
Regards, Kirill Yukhin

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-10-21  7:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-18  9:29 [Tarantool-patches] [PATCH v3] refactoring: wrap lua_newthread using luaT_cpcall Ilya Kosarev
2019-10-18 12:14 ` Igor Munkin
2019-10-18 14:08 ` [Tarantool-patches] [tarantool-patches] " Sergey Ostanevich
2019-10-21  7:51 ` Kirill Yukhin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox