@!visibility private @!macro internal_implementation_note
@!macro [attach] thread_local_var_method_initialize
Creates a thread local variable. @param [Object] default the default value when otherwise unset
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 43 def initialize(default = nil) @default = default allocate_storage end
@!visibility private
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 122 def self.thread_finalizer(array) proc do 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
@!visibility private
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 107 def self.threadlocal_finalizer(index) proc do 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
@!macro thread_local_var_method_bind
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 80 def bind(value, &block) if block_given? old_value = self.value begin self.value = value yield ensure self.value = old_value end end end
@!macro thread_local_var_method_get
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 49 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
@!macro thread_local_var_method_set
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 65 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
@!visibility private
# File lib/concurrent/atomic/ruby_thread_local_var.rb, line 95 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
Generated with the Darkfish Rdoc Generator 2.