From d077fdccae74d060c8a11f0907ea4e3a5425256b Mon Sep 17 00:00:00 2001 From: Joel Drapper Date: Tue, 26 Nov 2024 21:07:01 +0000 Subject: [PATCH] Add fiber isolation (#825) Thread locals are not Fiber-isolated and neither are Fiber locals Thread-isolated. The approach taken in this PR is to use a Thread local, storing the current fiber ID with the value. Then we can check the ids match when reading. --- lib/phlex/kit.rb | 3 ++- lib/phlex/sgml.rb | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/phlex/kit.rb b/lib/phlex/kit.rb index b66c7187..a12e58e2 100644 --- a/lib/phlex/kit.rb +++ b/lib/phlex/kit.rb @@ -60,7 +60,8 @@ def const_added(name) end define_singleton_method(name) do |*args, **kwargs, &block| - if (component = Thread.current[:__phlex_component__]) + component, fiber_id = Thread.current[:__phlex_component__] + if (component && fiber_id == Fiber.current.object_id) component.instance_exec do constant = me.const_get(name) render(constant.new(*args, **kwargs), &block) diff --git a/lib/phlex/sgml.rb b/lib/phlex/sgml.rb index e7baf112..bd9c595f 100644 --- a/lib/phlex/sgml.rb +++ b/lib/phlex/sgml.rb @@ -70,7 +70,7 @@ def call(buffer = +"", context: {}, view_context: nil, parent: nil, fragments: n return "" unless render? - Thread.current[:__phlex_component__] = self + Thread.current[:__phlex_component__] = [self, Fiber.current.object_id] phlex_context.around_render do before_template(&block) @@ -96,7 +96,7 @@ def call(buffer = +"", context: {}, view_context: nil, parent: nil, fragments: n buffer << phlex_context.buffer end ensure - Thread.current[:__phlex_component__] = parent + Thread.current[:__phlex_component__] = [parent, Fiber.current.object_id] end protected def __context__ = @_context