From 2131743e3bea9b7d923c02508ed10683209085e1 Mon Sep 17 00:00:00 2001 From: Nikolay Shirokovskiy <nshirokovskiy@tarantool.org> Date: Thu, 4 Jul 2024 14:03:46 +0300 Subject: [PATCH] fiber: phohibit fiber self join In this case join will just hang. Instead let's raise an error in case of Lua API and panic in case of C API. Closes #10196 NO_DOC=minor (cherry picked from commit 1e1bf36dbceafce625a8ce7e54951892cc8e2fa0) --- .../unreleased/gh-10196-fix-fiber-self-join-hang.md | 3 +++ src/lib/core/fiber.c | 3 +++ src/lib/core/fiber.h | 1 + src/lua/fiber.c | 2 ++ test/app-luatest/fiber_test.lua | 12 ++++++++++++ 5 files changed, 21 insertions(+) create mode 100644 changelogs/unreleased/gh-10196-fix-fiber-self-join-hang.md diff --git a/changelogs/unreleased/gh-10196-fix-fiber-self-join-hang.md b/changelogs/unreleased/gh-10196-fix-fiber-self-join-hang.md new file mode 100644 index 0000000000..872c3f4531 --- /dev/null +++ b/changelogs/unreleased/gh-10196-fix-fiber-self-join-hang.md @@ -0,0 +1,3 @@ +## bugfix/core + +* Fixed hang on fiber self join (gh-10196). diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c index cfc00ab741..b5782d9784 100644 --- a/src/lib/core/fiber.c +++ b/src/lib/core/fiber.c @@ -764,6 +764,9 @@ fiber_join_timeout(struct fiber *fiber, double timeout) if ((fiber->flags & FIBER_JOIN_BEEN_INVOKED) != 0) panic("join of a joined fiber detected"); + if (fiber() == fiber) + panic("cannot join itself"); + /* Prohibit joining the fiber and changing its joinability. */ fiber->flags |= FIBER_JOIN_BEEN_INVOKED; diff --git a/src/lib/core/fiber.h b/src/lib/core/fiber.h index c1e67c3858..959d084fb0 100644 --- a/src/lib/core/fiber.h +++ b/src/lib/core/fiber.h @@ -366,6 +366,7 @@ fiber_set_joinable(struct fiber *fiber, bool yesno); * * @pre FIBER_IS_JOINABLE flag is set (panic if not). * @pre the fiber is not joined yet (panic if not). + * @pre the fiber is different from current (panic if not). * * \param f fiber to be woken up * \return fiber function ret code diff --git a/src/lua/fiber.c b/src/lua/fiber.c index abe0c4efa4..3a922eaf8b 100644 --- a/src/lua/fiber.c +++ b/src/lua/fiber.c @@ -811,6 +811,8 @@ lbox_fiber_join(struct lua_State *L) if (!(fiber->flags & FIBER_IS_JOINABLE)) luaL_error(L, "the fiber is not joinable"); + if (fid == fiber()->fid) + luaL_error(L, "cannot join itself"); double timeout = TIMEOUT_INFINITY; if (!lua_isnoneornil(L, 2)) { if (!lua_isnumber(L, 2) || diff --git a/test/app-luatest/fiber_test.lua b/test/app-luatest/fiber_test.lua index 4aa262617e..55fd621e26 100644 --- a/test/app-luatest/fiber_test.lua +++ b/test/app-luatest/fiber_test.lua @@ -81,3 +81,15 @@ g.test_gh_10187_no_memory_leak_on_dead_fiber_search = function() collectgarbage() t.assert_equals(weak_table.fiber, nil) end + +g.test_gh_10196_no_hang_on_self_join = function() + local f = fiber.new(function() + fiber.self():join() + end) + f:set_joinable(true) + f:wakeup() + fiber.yield() + local ok, res = f:join() + t.assert_not(ok) + t.assert_error_msg_contains('cannot join itself', box.error, res) +end -- GitLab