summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrm155 <[email protected]>2021-07-30 15:45:34 -0400
committerHiroshi SHIBATA <[email protected]>2024-10-01 17:59:42 +0900
commit136b30b414b3fcaddf0505d5a72fed8b08b2da3c (patch)
treeff2106cdadb16f69450b2d5355f6e33391292c59
parent76111af632a0689cbe56787b0fb1ba4c8bbbe2e0 (diff)
[ruby/singleton] Improve Ractor-compliance; Create PerRactorSingleton
https://github.com/ruby/singleton/commit/ec4f66d9c1
-rw-r--r--lib/singleton.rb104
1 files changed, 85 insertions, 19 deletions
diff --git a/lib/singleton.rb b/lib/singleton.rb
index 6da939124e..577a7b8894 100644
--- a/lib/singleton.rb
+++ b/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