diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-12-11 17:45:27 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-12-11 18:52:02 -0300 |
commit | a565f80bcb0dd9687330d5644ce9baef58e9c835 (patch) | |
tree | e71f6fd1074b5539cd5fc5c5fe47fdb9655e49d0 /activesupport/lib | |
parent | 48583f8bf74d1cefefea3cd6591bd546a9eaff6c (diff) | |
download | rails-a565f80bcb0dd9687330d5644ce9baef58e9c835.tar.gz rails-a565f80bcb0dd9687330d5644ce9baef58e9c835.tar.bz2 rails-a565f80bcb0dd9687330d5644ce9baef58e9c835.zip |
Backport thread-local variables from Ruby 2.0
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/core_ext/thread.rb | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/core_ext/thread.rb b/activesupport/lib/active_support/core_ext/thread.rb new file mode 100644 index 0000000000..6ad0b2d69c --- /dev/null +++ b/activesupport/lib/active_support/core_ext/thread.rb @@ -0,0 +1,70 @@ +class Thread + LOCK = Mutex.new # :nodoc: + + # Returns the value of a thread local variable that has been set. Note that + # these are different than fiber local values. + # + # Thread local values are carried along with threads, and do not respect + # fibers. For example: + # + # Thread.new { + # Thread.current.thread_variable_set("foo", "bar") # set a thread local + # Thread.current["foo"] = "bar" # set a fiber local + # + # Fiber.new { + # Fiber.yield [ + # Thread.current.thread_variable_get("foo"), # get the thread local + # Thread.current["foo"], # get the fiber local + # ] + # }.resume + # }.join.value # => ['bar', nil] + # + # The value <tt>"bar"</tt> is returned for the thread local, where +nil+ is returned + # for the fiber local. The fiber is executed in the same thread, so the + # thread local values are available. + def thread_variable_get(key) + locals[key.to_sym] + end + + # Sets a thread local with +key+ to +value+. Note that these are local to + # threads, and not to fibers. Please see Thread#thread_variable_get for + # more information. + def thread_variable_set(key, value) + locals[key.to_sym] = value + end + + # Returns an an array of the names of the thread-local variables (as Symbols). + # + # thr = Thread.new do + # Thread.current.thread_variable_set(:cat, 'meow') + # Thread.current.thread_variable_set("dog", 'woof') + # end + # thr.join #=> #<Thread:0x401b3f10 dead> + # thr.thread_variables #=> [:dog, :cat] + # + # Note that these are not fiber local variables. Please see Thread#thread_variable_get + # for more details. + def thread_variables + locals.keys + end + + # Returns <tt>true</tt> if the given string (or symbol) exists as a + # thread-local variable. + # + # me = Thread.current + # me.thread_variable_set(:oliver, "a") + # me.thread_variable?(:oliver) #=> true + # me.thread_variable?(:stanley) #=> false + # + # Note that these are not fiber local variables. Please see Thread#thread_variable_get + # for more details. + def thread_variable?(key) + locals.has_key?(key.to_sym) + end + + private + + def locals + @locals || LOCK.synchronize { @locals ||= {} } + end +end unless Thread.instance_methods.include?(:thread_variable_set) |