class Concurrent::RubyThreadLocalVar
@!visibility private @!macro internal_implementation_note
Constants
- ARRAYS
- FREE
@!visibility private
- LOCK
Protected Class Methods
thread_finalizer(array)
click to toggle source
@!visibility private
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 101 def self.thread_finalizer(array) proc do Thread.new do # avoid error: can't be called from trap context LOCK.synchronize do # The thread which used this thread-local array is now gone # So don't hold onto a reference to the array (thus blocking GC) ARRAYS.delete(array.object_id) end end end end
threadlocal_finalizer(index)
click to toggle source
@!visibility private
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 84 def self.threadlocal_finalizer(index) proc do Thread.new do # avoid error: can't be called from trap context LOCK.synchronize do FREE.push(index) # The cost of GC'ing a TLV is linear in the number of threads using TLVs # But that is natural! More threads means more storage is used per TLV # So naturally more CPU time is required to free more storage ARRAYS.each_value do |array| array[index] = nil end end end end end
Public Instance Methods
value()
click to toggle source
@!macro thread_local_var_method_get
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 39 def value if array = get_threadlocal_array value = array[@index] if value.nil? default elsif value.equal?(NULL) nil else value end else default end end
value=(value)
click to toggle source
@!macro thread_local_var_method_set
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 55 def value=(value) me = Thread.current # We could keep the thread-local arrays in a hash, keyed by Thread # But why? That would require locking # Using Ruby's built-in thread-local storage is faster unless array = get_threadlocal_array(me) array = set_threadlocal_array([], me) LOCK.synchronize { ARRAYS[array.object_id] = array } ObjectSpace.define_finalizer(me, self.class.thread_finalizer(array)) end array[@index] = (value.nil? ? NULL : value) value end
Protected Instance Methods
allocate_storage()
click to toggle source
@!visibility private
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 72 def allocate_storage @index = LOCK.synchronize do FREE.pop || begin result = @@next @@next += 1 result end end ObjectSpace.define_finalizer(self, self.class.threadlocal_finalizer(@index)) end