From 871e7d2f5d1a9cc1821662c1c5911a876a873e3b Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Tue, 17 Mar 2026 13:31:55 +0100 Subject: [PATCH 1/4] Fix: return thread to pool after scheduler shutdown [fixup #15885] --- src/fiber/execution_context/parallel/scheduler.cr | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fiber/execution_context/parallel/scheduler.cr b/src/fiber/execution_context/parallel/scheduler.cr index b71c48279e19..4d8745a69084 100644 --- a/src/fiber/execution_context/parallel/scheduler.cr +++ b/src/fiber/execution_context/parallel/scheduler.cr @@ -35,7 +35,12 @@ module Fiber::ExecutionContext @global_queue = @execution_context.global_queue @runnables = Runnables(256).new(@global_queue) @event_loop = @execution_context.event_loop - @main_fiber = Fiber.new("#{@name}:loop", @execution_context) { run_loop } + + @main_fiber = Fiber.new("#{@name}:loop", @execution_context) do + run_loop + ensure + ExecutionContext.thread_pool.checkin + end end protected def shutdown! : Nil From b8a397e6b8bf7f8d2ed73fde5280ed04bf6db771 Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 20 Mar 2026 11:50:28 +0100 Subject: [PATCH 2/4] Group event loop unregistration and thread pool checking to main fiber block --- src/fiber/execution_context/parallel/scheduler.cr | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fiber/execution_context/parallel/scheduler.cr b/src/fiber/execution_context/parallel/scheduler.cr index 4d8745a69084..e836205b84e1 100644 --- a/src/fiber/execution_context/parallel/scheduler.cr +++ b/src/fiber/execution_context/parallel/scheduler.cr @@ -39,6 +39,7 @@ module Fiber::ExecutionContext @main_fiber = Fiber.new("#{@name}:loop", @execution_context) do run_loop ensure + @event_loop.unregister(self) ExecutionContext.thread_pool.checkin end end @@ -158,8 +159,6 @@ module Fiber::ExecutionContext Crystal.print_error_buffered("BUG: %s#run_loop [%s] crashed", self.class.name, @name, exception: exception) end - ensure - @event_loop.unregister(self) end private def find_next_runnable : Fiber? From da1a718539b56dba2bd905db1c2449cca01f8e4b Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 20 Mar 2026 11:53:07 +0100 Subject: [PATCH 3/4] Revert "Group event loop unregistration and thread pool checking to main fiber block" This reverts commit b8a397e6b8bf7f8d2ed73fde5280ed04bf6db771. --- src/fiber/execution_context/parallel/scheduler.cr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fiber/execution_context/parallel/scheduler.cr b/src/fiber/execution_context/parallel/scheduler.cr index e836205b84e1..4d8745a69084 100644 --- a/src/fiber/execution_context/parallel/scheduler.cr +++ b/src/fiber/execution_context/parallel/scheduler.cr @@ -39,7 +39,6 @@ module Fiber::ExecutionContext @main_fiber = Fiber.new("#{@name}:loop", @execution_context) do run_loop ensure - @event_loop.unregister(self) ExecutionContext.thread_pool.checkin end end @@ -159,6 +158,8 @@ module Fiber::ExecutionContext Crystal.print_error_buffered("BUG: %s#run_loop [%s] crashed", self.class.name, @name, exception: exception) end + ensure + @event_loop.unregister(self) end private def find_next_runnable : Fiber? From 72a1d5a008776bb5122e1263ed64452dfbb112d6 Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 20 Mar 2026 11:54:23 +0100 Subject: [PATCH 4/4] move thread pool checkin to run_loop --- src/fiber/execution_context/parallel/scheduler.cr | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/fiber/execution_context/parallel/scheduler.cr b/src/fiber/execution_context/parallel/scheduler.cr index 4d8745a69084..48c48c26a251 100644 --- a/src/fiber/execution_context/parallel/scheduler.cr +++ b/src/fiber/execution_context/parallel/scheduler.cr @@ -35,12 +35,7 @@ module Fiber::ExecutionContext @global_queue = @execution_context.global_queue @runnables = Runnables(256).new(@global_queue) @event_loop = @execution_context.event_loop - - @main_fiber = Fiber.new("#{@name}:loop", @execution_context) do - run_loop - ensure - ExecutionContext.thread_pool.checkin - end + @main_fiber = Fiber.new("#{@name}:loop", @execution_context) { run_loop } end protected def shutdown! : Nil @@ -160,6 +155,7 @@ module Fiber::ExecutionContext end ensure @event_loop.unregister(self) + ExecutionContext.thread_pool.checkin end private def find_next_runnable : Fiber?