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 0000000000000000000000000000000000000000..872c3f4531673a79ee3e8f130babfa90427b6d65 --- /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 cfc00ab741aa2bd6bdf23ac03306e5f3caca87b9..b5782d9784db9de7a449280e55d7b42a6acbaeb2 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 c1e67c38587c6ea133f92bebf4ce042591251f77..959d084fb0c84902975a15ae1f6c17af3f3c0cd6 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 abe0c4efa41e7ffa0f074b6b5cbe2066c00fb74d..3a922eaf8bc20494954fea61f3a301d0d411dcc9 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 4aa262617e33f58cf5f4107eb3002527268d13f1..55fd621e2660867315510c29df875fb7c51ef439 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