mirror of
https://github.com/github/rails.git
synced 2026-01-09 14:48:01 -05:00
Prevent concurrent compilation of templates - closes #6400
This commit is contained in:
@@ -2,6 +2,7 @@ require 'active_support/core_ext/array/wrap'
|
||||
require 'active_support/core_ext/object/blank'
|
||||
require 'active_support/core_ext/object/try'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'thread'
|
||||
|
||||
module ActionView
|
||||
# = Action View Template
|
||||
@@ -123,6 +124,7 @@ module ActionView
|
||||
@virtual_path = details[:virtual_path]
|
||||
@updated_at = details[:updated_at] || Time.now
|
||||
@formats = Array.wrap(format).map { |f| f.is_a?(Mime::Type) ? f.ref : f }
|
||||
@compile_mutex = Mutex.new
|
||||
end
|
||||
|
||||
# Returns if the underlying handler supports streaming. If so,
|
||||
@@ -224,18 +226,28 @@ module ActionView
|
||||
def compile!(view) #:nodoc:
|
||||
return if @compiled
|
||||
|
||||
if view.is_a?(ActionView::CompiledTemplates)
|
||||
mod = ActionView::CompiledTemplates
|
||||
else
|
||||
mod = view.singleton_class
|
||||
# Templates can be used concurrently in threaded environments
|
||||
# so compilation and any instance variable modification must
|
||||
# be synchronized
|
||||
@compile_mutex.synchronize do
|
||||
# Any thread holding this lock will be compiling the template needed
|
||||
# by the threads waiting. So re-check the @compiled flag to avoid
|
||||
# re-compilation
|
||||
return if @compiled
|
||||
|
||||
if view.is_a?(ActionView::CompiledTemplates)
|
||||
mod = ActionView::CompiledTemplates
|
||||
else
|
||||
mod = view.singleton_class
|
||||
end
|
||||
|
||||
compile(view, mod)
|
||||
|
||||
# Just discard the source if we have a virtual path. This
|
||||
# means we can get the template back.
|
||||
@source = nil if @virtual_path
|
||||
@compiled = true
|
||||
end
|
||||
|
||||
compile(view, mod)
|
||||
|
||||
# Just discard the source if we have a virtual path. This
|
||||
# means we can get the template back.
|
||||
@source = nil if @virtual_path
|
||||
@compiled = true
|
||||
end
|
||||
|
||||
# Among other things, this method is responsible for properly setting
|
||||
|
||||
Reference in New Issue
Block a user