Thread Safety

Use "Thread.current[:included_by]" instead of  the Class variable,
"@@included_by".

The former will work on some newfangled multi-threaded Webserver stack,
which uses separate threads to handle multiple simlutaneous requests
(one request/thread). Dunno that the rest of the application is
thread-safe, but using a class variable, in this context, probably isn't.

Thanks to Sam Ruby for the suggestion.
This commit is contained in:
Jacques Distler 2008-12-23 16:27:34 -06:00
parent 1b54b695c3
commit 3a109d1c82

View file

@ -10,14 +10,14 @@ require 'chunks/wiki'
class Include < WikiChunk::WikiReference class Include < WikiChunk::WikiReference
INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]+?)\s*\]\]/i INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]+?)\s*\]\]/i
@@included_by = [] Thread.current[:included_by] = []
def self.pattern() INCLUDE_PATTERN end def self.pattern() INCLUDE_PATTERN end
def initialize(match_data, content) def initialize(match_data, content)
super super
@page_name = match_data[1].strip @page_name = match_data[1].strip
rendering_mode = content.options[:mode] || :show rendering_mode = content.options[:mode] || :show
@@included_by.push(@content.page_name) Thread.current[:included_by].push(@content.page_name)
@unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode) @unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode)
end end
@ -25,9 +25,9 @@ class Include < WikiChunk::WikiReference
def get_unmask_text_avoiding_recursion_loops(rendering_mode) def get_unmask_text_avoiding_recursion_loops(rendering_mode)
if refpage if refpage
if @@included_by.include?(refpage.page.name) if Thread.current[:included_by].include?(refpage.page.name)
@content.delete_chunk(self) @content.delete_chunk(self)
@@included_by = [] Thread.current[:included_by] = []
return "<em>Recursive include detected: #{@content.page_name} &#x2192; #{@content.page_name}</em>\n" return "<em>Recursive include detected: #{@content.page_name} &#x2192; #{@content.page_name}</em>\n"
end end
# TODO This way of instantiating a renderer is ugly. # TODO This way of instantiating a renderer is ugly.
@ -41,10 +41,10 @@ class Include < WikiChunk::WikiReference
raise "Unsupported rendering mode #{@mode.inspect}" raise "Unsupported rendering mode #{@mode.inspect}"
end end
@content.merge_chunks(included_content) @content.merge_chunks(included_content)
@@included_by = [] Thread.current[:included_by] = []
return included_content.pre_rendered return included_content.pre_rendered
else else
@@included_by = [] Thread.current[:included_by] = []
return "<em>Could not include #{@page_name}</em>\n" return "<em>Could not include #{@page_name}</em>\n"
end end
end end