diff --git a/src/main.cc b/src/main.cc index 65b41362f49626edada533cecb84cbdea06da33c..9f0bc3be15097d5f1ac35fb73dc633efe5a95242 100644 --- a/src/main.cc +++ b/src/main.cc @@ -147,6 +147,10 @@ on_shutdown_f(va_list ap) if (ev_depth(loop()) == 0) fiber_sleep(0.0); + /* Handle spurious wakeups. */ + while (!is_shutting_down) + fiber_yield(); + if (trigger_fiber_run(&box_on_shutdown_trigger_list, NULL, on_shutdown_trigger_timeout) != 0) { say_error("on_shutdown triggers failed"); @@ -172,7 +176,7 @@ tarantool_exit(int code) is_shutting_down = true; exit_code = code; box_broadcast_fmt("box.shutdown", "%b", true); - fiber_call(on_shutdown_fiber); + fiber_wakeup(on_shutdown_fiber); } static void @@ -770,16 +774,9 @@ main(int argc, char **argv) box_lua_init(tarantool_L); /* * Reserve a fiber to run on_shutdown triggers. - * Make sure the fiber is non-cancellable so that - * it doesn't get woken up from Lua unintentionally. */ - struct fiber_attr attr; - fiber_attr_create(&attr); - attr.flags |= FIBER_IS_SYSTEM; - attr.flags &= ~FIBER_IS_CANCELLABLE; - on_shutdown_fiber = fiber_new_ex("on_shutdown", - &attr, - on_shutdown_f); + on_shutdown_fiber = fiber_new_system("on_shutdown", + on_shutdown_f); if (on_shutdown_fiber == NULL) diag_raise(); diff --git a/test/app-luatest/gh_7166_wakeup_on_shutdown_fiber_test.lua b/test/app-luatest/gh_7166_wakeup_on_shutdown_fiber_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..40e61a44e5a4543a9074b2af4eeca2a95c94e161 --- /dev/null +++ b/test/app-luatest/gh_7166_wakeup_on_shutdown_fiber_test.lua @@ -0,0 +1,9 @@ +local t = require('luatest') +local g = t.group('gh-7166') + +-- Check that wake up of the shutdown fiber doesn't crash Tarantool +g.test_wakeup_on_shutdown_fiber = function() + local lt_fiber = require('test.luatest_helpers.fiber') + local f = lt_fiber.find_by_name('on_shutdown') + f:wakeup() +end diff --git a/test/luatest_helpers/fiber.lua b/test/luatest_helpers/fiber.lua new file mode 100644 index 0000000000000000000000000000000000000000..9eefb5746ab64567e74417d0adf7164432929725 --- /dev/null +++ b/test/luatest_helpers/fiber.lua @@ -0,0 +1,15 @@ +local fiber = require('fiber') + +-- Searches for a fiber with the specified name and returns the fiber object +local function find_by_name(name) + for id, f in pairs(fiber.info()) do + if f.name == name then + return fiber.find(id) + end + end + return nil +end + +return { + find_by_name = find_by_name +}