[Tarantool-patches] [PATCH] Make fibers joinable by default

Max Melentiev m.melentiev at corp.mail.ru
Wed Dec 11 12:47:09 MSK 2019


"Joinable" flag at fiber is an implementation details
and should not bother end users.

This patch makes every new fiber joinable and registers
GC callback for it. GC'ed fiber can be either dead or
alive. As there is no more ref to the fiber from lua
it means that dead one can be recycled and alive one
can be marked as not joinable so it can be fully recycled
automatically later.

This makes set_joinable obsolete, however the patch
is completely backward-compatible.

@TarantoolBot document
Title: Remove set_joinable from docs or mark it obsolete
As of all fibers are joinable by default
set_joinable got useless.
---
 src/lib/core/fiber.c |  5 +----
 src/lib/core/fiber.h |  3 +++
 src/lua/fiber.c      | 31 +++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c
index b813c1739..e1e5f68f1 100644
--- a/src/lib/core/fiber.c
+++ b/src/lib/core/fiber.c
@@ -193,9 +193,6 @@ fiber_attr_getstacksize(struct fiber_attr *fiber_attr)
 				    fiber_attr_default.stack_size;
 }
 
-static void
-fiber_recycle(struct fiber *fiber);
-
 static void
 fiber_stack_recycle(struct fiber *fiber);
 
@@ -659,7 +656,7 @@ fiber_reset(struct fiber *fiber)
 }
 
 /** Destroy an active fiber and prepare it for reuse. */
-static void
+void
 fiber_recycle(struct fiber *fiber)
 {
 	/* no exceptions are leaking */
diff --git a/src/lib/core/fiber.h b/src/lib/core/fiber.h
index fb168e25e..c4ce8f4cf 100644
--- a/src/lib/core/fiber.h
+++ b/src/lib/core/fiber.h
@@ -234,6 +234,9 @@ fiber_wakeup(struct fiber *f);
 API_EXPORT void
 fiber_cancel(struct fiber *f);
 
+API_EXPORT void
+fiber_recycle(struct fiber *fiber);
+
 /**
  * Make it possible or not possible to wakeup the current
  * fiber immediately when it's cancelled.
diff --git a/src/lua/fiber.c b/src/lua/fiber.c
index 336be60a2..7170a3a9c 100644
--- a/src/lua/fiber.c
+++ b/src/lua/fiber.c
@@ -382,6 +382,35 @@ lua_fiber_run_f(MAYBE_UNUSED va_list ap)
 	return result;
 }
 
+/**
+ * Fiber is created joinable by default so it must be marked
+ * as not joinable before it's dead.
+ * If GC'ed fiber is already dead it's simply recycled
+ * the same way as fiber_join do.
+ */
+static int
+lbox_fiber_gc(lua_State *L) {
+	int index = 1;
+	uint32_t fid;
+	if (lua_type(L, index) == LUA_TNUMBER) {
+		fid = lua_tonumber(L, index);
+	} else {
+		fid = *(uint32_t *) luaL_checkudata(L, index, fiberlib_name);
+	}
+	struct fiber *fiber = fiber_find(fid);
+	if (fiber != NULL) {
+		if (fiber_is_dead(fiber)) {
+			fiber_recycle(fiber);
+		} else {
+			fiber_set_joinable(fiber, false);
+		}
+	}
+
+	lua_pushboolean(L, true);
+	lua_pushinteger(L, 0);
+	return 2;
+}
+
 /**
  * Utility function for fiber.create and fiber.new
  */
@@ -401,6 +430,7 @@ fiber_create(struct lua_State *L)
 	lua_xmove(L, child_L, lua_gettop(L));
 	/* XXX: 'fiber' is leaked if this throws a Lua error. */
 	lbox_pushfiber(L, f->fid);
+	fiber_set_joinable(f, true);
 	/* Pass coro_ref via lua stack so that we don't have to pass it
 	 * as an argument of fiber_run function.
 	 * No function will work with child_L until the function is called.
@@ -736,6 +766,7 @@ static const struct luaL_Reg lbox_fiber_meta [] = {
 	{"set_joinable", lbox_fiber_set_joinable},
 	{"wakeup", lbox_fiber_wakeup},
 	{"__index", lbox_fiber_index},
+	{"__gc", lbox_fiber_gc},
 	{NULL, NULL}
 };
 
-- 
2.21.0



More information about the Tarantool-patches mailing list