class Tool::ThreadLocal

Have thread local values without them actually being thread global.

Advantages:

@example To replace Thread.current hash access

local = Tool::ThreadLocal.new
local[:key] = "value"

Thread.new do
  local[:key] = "other value"
  puts local[:key] # other value
end.join

puts local[:key] # value

@example Usage with Array

local = Tool::ThreadLocal.new([:foo])
local << :bar

Thread.new { p local }.join # [:foo]
p local # [:foo, :bar]

Public Class Methods

cleanup(id) click to toggle source

Thread finalizer. @!visibility private

# File lib/tool/thread_local.rb, line 37
def self.cleanup(id)
  @locals.keep_if do |local|
    next false unless local.weakref_alive?
    local.__cleanup__
    true
  end
end
new(*) click to toggle source

@see initialize @!visibility private

Calls superclass method
# File lib/tool/thread_local.rb, line 57
def self.new(*)
  result = super
  @mutex.synchronize { @locals << WeakRef.new(result) }
  result
end
new(default = {}) click to toggle source
# File lib/tool/thread_local.rb, line 63
def initialize(default = {})
  @default = default.dup
  @map     = {}
end
ref(thread) click to toggle source

Generates weak reference to thread and sets up finalizer. @return [WeakRef] @!visibility private

# File lib/tool/thread_local.rb, line 48
def self.ref(thread)
  thread[:weakref] ||= begin
    ObjectSpace.define_finalizer(thread, method(:cleanup))
    WeakRef.new(thread)
  end
end

Public Instance Methods

__cleanup__() click to toggle source

Remove locals for dead or GC'ed threads @!visibility private

# File lib/tool/thread_local.rb, line 83
def __cleanup__
  @map.keep_if { |key, value| key.weakref_alive? and key.alive? }
end
__getobj__() click to toggle source

@see Delegator @!visibility private

# File lib/tool/thread_local.rb, line 70
def __getobj__
  ref = ::Tool::ThreadLocal.ref(Thread.current)
  @map[ref] ||= @default.dup
end
__size__() click to toggle source

@return [Integer] number of threads with specific locals @!visibility private

# File lib/tool/thread_local.rb, line 77
def __size__
  @map.size
end