[ruby/singleton] Improve Ractor-compliance; Create PerRactorSingleton
https://github.com/ruby/singleton/commit/ec4f66d9c1
This commit is contained in:
parent
76111af632
commit
136b30b414
104
lib/singleton.rb
104
lib/singleton.rb
@ -93,21 +93,25 @@
|
||||
#
|
||||
module Singleton
|
||||
VERSION = "0.2.0"
|
||||
VERSION.freeze
|
||||
|
||||
# Raises a TypeError to prevent cloning.
|
||||
def clone
|
||||
raise TypeError, "can't clone instance of singleton #{self.class}"
|
||||
end
|
||||
module SingletonInstanceMethods
|
||||
# Raises a TypeError to prevent cloning.
|
||||
def clone
|
||||
raise TypeError, "can't clone instance of singleton #{self.class}"
|
||||
end
|
||||
|
||||
# Raises a TypeError to prevent duping.
|
||||
def dup
|
||||
raise TypeError, "can't dup instance of singleton #{self.class}"
|
||||
end
|
||||
# Raises a TypeError to prevent duping.
|
||||
def dup
|
||||
raise TypeError, "can't dup instance of singleton #{self.class}"
|
||||
end
|
||||
|
||||
# By default, do not retain any state when marshalling.
|
||||
def _dump(depth = -1)
|
||||
''
|
||||
# By default, do not retain any state when marshalling.
|
||||
def _dump(depth = -1)
|
||||
''
|
||||
end
|
||||
end
|
||||
include SingletonInstanceMethods
|
||||
|
||||
module SingletonClassMethods # :nodoc:
|
||||
|
||||
@ -121,7 +125,7 @@ module Singleton
|
||||
end
|
||||
|
||||
def instance # :nodoc:
|
||||
@singleton__instance__ || @singleton__mutex__.synchronize { @singleton__instance__ ||= new }
|
||||
@singleton__instance__ || @singleton__mutex__.synchronize { @singleton__instance__ ||= set_instance(new) }
|
||||
end
|
||||
|
||||
private
|
||||
@ -130,22 +134,42 @@ module Singleton
|
||||
super
|
||||
Singleton.__init__(sub_klass)
|
||||
end
|
||||
|
||||
def set_instance(val)
|
||||
@singleton__instance__ = val
|
||||
end
|
||||
|
||||
def set_mutex(val)
|
||||
@singleton__mutex__ = val
|
||||
end
|
||||
end
|
||||
|
||||
class << Singleton # :nodoc:
|
||||
def self.module_with_class_methods
|
||||
SingletonClassMethods
|
||||
end
|
||||
|
||||
module SingletonClassProperties
|
||||
|
||||
def self.included(c)
|
||||
# extending an object with Singleton is a bad idea
|
||||
c.undef_method :extend_object
|
||||
end
|
||||
|
||||
def self.extended(c)
|
||||
# extending an object with Singleton is a bad idea
|
||||
c.singleton_class.undef_method :extend_object
|
||||
end
|
||||
|
||||
def __init__(klass) # :nodoc:
|
||||
klass.instance_eval {
|
||||
@singleton__instance__ = nil
|
||||
@singleton__mutex__ = Thread::Mutex.new
|
||||
set_instance(nil)
|
||||
set_mutex(Thread::Mutex.new)
|
||||
}
|
||||
klass
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# extending an object with Singleton is a bad idea
|
||||
undef_method :extend_object
|
||||
|
||||
def append_features(mod)
|
||||
# help out people counting on transitive mixins
|
||||
unless mod.instance_of?(Class)
|
||||
@ -157,10 +181,11 @@ module Singleton
|
||||
def included(klass)
|
||||
super
|
||||
klass.private_class_method :new, :allocate
|
||||
klass.extend SingletonClassMethods
|
||||
klass.extend module_with_class_methods
|
||||
Singleton.__init__(klass)
|
||||
end
|
||||
end
|
||||
extend SingletonClassProperties
|
||||
|
||||
##
|
||||
# :singleton-method: _load
|
||||
@ -170,3 +195,44 @@ module Singleton
|
||||
# :singleton-method: instance
|
||||
# Returns the singleton instance.
|
||||
end
|
||||
|
||||
module PerRactorSingleton
|
||||
include Singleton::SingletonInstanceMethods
|
||||
|
||||
module PerRactorSingletonClassMethods
|
||||
include Singleton::SingletonClassMethods
|
||||
def instance
|
||||
set_mutex(Thread::Mutex.new) if Ractor.current[mutex_key].nil?
|
||||
return Ractor.current[instance_key] if Ractor.current[instance_key]
|
||||
Ractor.current[mutex_key].synchronize {
|
||||
return Ractor.current[instance_key] if Ractor.current[instance_key]
|
||||
set_instance(new())
|
||||
}
|
||||
Ractor.current[instance_key]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def instance_key
|
||||
:"__PerRactorSingleton_instance_with_class_id_#{object_id}__"
|
||||
end
|
||||
|
||||
def mutex_key
|
||||
:"__PerRactorSingleton_mutex_with_class_id_#{object_id}__"
|
||||
end
|
||||
|
||||
def set_instance(val)
|
||||
Ractor.current[instance_key] = val
|
||||
end
|
||||
|
||||
def set_mutex(val)
|
||||
Ractor.current[mutex_key] = val
|
||||
end
|
||||
end
|
||||
|
||||
def self.module_with_class_methods
|
||||
PerRactorSingletonClassMethods
|
||||
end
|
||||
|
||||
extend Singleton::SingletonClassProperties
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user