class ThreadLocal

Constants

VERSION

Public Class Methods

new(initial_value, *args) click to toggle source
# File lib/thread_local.rb, line 6
def initialize(initial_value, *args)
  opts, = args

  opts ||= {}

  @initial_value = to_callable(initial_value)
  @prefix = opts[:prefix] || 'thread_local'

  @threads_mutex = Mutex.new
  @threads = Set.new

  define_initializer!
end

Public Instance Methods

__threads_object_ids__() click to toggle source
# File lib/thread_local.rb, line 60
def __threads_object_ids__
  @threads
end
delete() click to toggle source
# File lib/thread_local.rb, line 50
def delete
  t = Thread.current

  t.thread_variable_set value_key, nil

  @threads_mutex.synchronize do
    @threads.delete(t.object_id)
  end
end
get() click to toggle source
# File lib/thread_local.rb, line 20
def get
  t = Thread.current

  if set?
    t.thread_variable_get value_key
  else
    set @initial_value.call
  end
end
set(new_value) click to toggle source
# File lib/thread_local.rb, line 35
def set(new_value)
  t = Thread.current

  t.thread_variable_set value_key, new_value
  t.thread_variable_set value_initialized_key, true

  forget_vanished_threads!

  @threads_mutex.synchronize do
    @threads.add(t.object_id)
  end

  new_value
end
set?() click to toggle source
# File lib/thread_local.rb, line 30
def set?
  t = Thread.current
  t.thread_variable_get value_initialized_key
end

Private Instance Methods

collect_threads_object_ids() click to toggle source
# File lib/thread_local.rb, line 86
def collect_threads_object_ids
  Thread.list.map(&:object_id)
end
collect_threads_object_ids_as_set() click to toggle source
# File lib/thread_local.rb, line 90
def collect_threads_object_ids_as_set
  Set.new(collect_threads_object_ids)
end
define_initializer!() click to toggle source
# File lib/thread_local.rb, line 104
def define_initializer!
  ObjectSpace.define_finalizer self do
    # We don't synchronize `@threads` here,
    # assuming that this finalizer won't be called concurrently with `ThreadLocal#set`
    @threads.each do |threads_object_id|
      t = Thread.all.find do |t|
        t.object_id == threads_object_id
      end

      unless t.nil?
        t.thread_variable_set key, nil
      end
    end
  end
end
forget_vanished_threads!() click to toggle source
# File lib/thread_local.rb, line 94
def forget_vanished_threads!
  set = collect_threads_object_ids_as_set

  @threads_mutex.synchronize do |t|
    @threads.select do |threads_object_id|
      set.include? threads_object_id
    end
  end
end
to_callable(possibly_callable_object) click to toggle source

@param [Object] possibly_callable_object @return Proc

# File lib/thread_local.rb, line 78
def to_callable(possibly_callable_object)
  if possibly_callable_object.respond_to? :call
    possibly_callable_object
  else
    -> { possibly_callable_object }
  end
end
value_initialized_key() click to toggle source

@return String

# File lib/thread_local.rb, line 72
def value_initialized_key
  "#{@prefix}_#{object_id}_initialized"
end
value_key() click to toggle source

@return String

# File lib/thread_local.rb, line 67
def value_key
  "#{@prefix}_#{object_id}"
end