From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp16.mail.ru (smtp16.mail.ru [94.100.176.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 2BDB046971A for ; Wed, 11 Dec 2019 12:47:22 +0300 (MSK) From: Max Melentiev Date: Wed, 11 Dec 2019 12:47:09 +0300 Message-Id: <20191211094709.46680-1-m.melentiev@corp.mail.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH] Make fibers joinable by default List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org "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