aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2012-05-20 14:01:52 -0700
committerJosé Valim <jose.valim@gmail.com>2012-05-20 14:01:52 -0700
commitfe9731ee674b8d7d7e06f81441fceb0499734493 (patch)
treefc6f6212c9259da97e5b5aa2c862ae46cdc168bc /actionpack/lib/action_view
parent6ef9fda1a39f45e2d18aba4881f60a19589a2c77 (diff)
parent565c1b0a0772ac6cf91c77e9285806f7b028614c (diff)
downloadrails-fe9731ee674b8d7d7e06f81441fceb0499734493.tar.gz
rails-fe9731ee674b8d7d7e06f81441fceb0499734493.tar.bz2
rails-fe9731ee674b8d7d7e06f81441fceb0499734493.zip
Merge pull request #6407 from pinetops/565c1b0a0772ac6cf91c77e9285806f7b028614c
Template concurrency fixes
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/template.rb32
1 files changed, 22 insertions, 10 deletions
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index eac6287b0b..e67e52cc76 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -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
- end
+ # 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)
+ 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
+ # 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
end
# Among other things, this method is responsible for properly setting