diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-12-31 15:02:22 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-12-31 15:02:22 +0000 |
commit | a3e1b1ce7ed7e7ffac23015fc2fde56511b30681 (patch) | |
tree | 7b725552a9a4ded93849ca2faab1b257f7761790 /lib/singleton.rb | |
parent | 3e7566d8fb5138bb9cd647e5fdefc54fc9803509 (diff) | |
download | ruby-a3e1b1ce7ed7e7ffac23015fc2fde56511b30681.tar.gz |
* Merge YARV
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11439 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/singleton.rb')
-rw-r--r-- | lib/singleton.rb | 125 |
1 files changed, 40 insertions, 85 deletions
diff --git a/lib/singleton.rb b/lib/singleton.rb index 0ab8517275..2c08f35e37 100644 --- a/lib/singleton.rb +++ b/lib/singleton.rb @@ -60,7 +60,7 @@ # and _dump(depth) hooks allows the (partially) resurrections of # a previous state of ``the instance''. - +require 'thread' module Singleton # disable build-in copying methods @@ -72,65 +72,19 @@ module Singleton end private + # default marshalling strategy - def _dump(depth=-1) + def _dump(depth = -1) '' end -end - -class << Singleton - # Method body of first instance call. - FirstInstanceCall = proc do - # @__instance__ takes on one of the following values - # * nil - before and after a failed creation - # * false - during creation - # * sub_class instance - after a successful creation - # the form makes up for the lack of returns in progs - Thread.critical = true - if @__instance__.nil? - @__instance__ = false - Thread.critical = false - begin - @__instance__ = new - ensure - if @__instance__ - class <<self - remove_method :instance - def instance; @__instance__ end - end - else - @__instance__ = nil # failed instance creation - end - end - elsif _instantiate?() - Thread.critical = false - else - @__instance__ = false - Thread.critical = false - begin - @__instance__ = new - ensure - if @__instance__ - class <<self - remove_method :instance - def instance; @__instance__ end - end - else - @__instance__ = nil - end - end - end - @__instance__ - end - module SingletonClassMethods # properly clone the Singleton pattern - did you know # that duping doesn't copy class methods? def clone Singleton.__init__(super) end - + private # ensure that the Singleton pattern is properly inherited @@ -142,46 +96,47 @@ class << Singleton def _load(str) instance end - - # waiting-loop hook - def _instantiate?() - while false.equal?(@__instance__) - Thread.critical = false - sleep(0.08) # timeout - Thread.critical = true + end + + class << Singleton + def __init__(klass) + klass.instance_eval { + @__instance__ = nil + @__mutex__ = Mutex.new + } + def klass.instance + return @__instance__ if @__instance__ + @__mutex__.synchronize { + return @__instance__ if @__instance__ + @__instance__ = new() + } + @__instance__ end - @__instance__ + klass end - end - - def __init__(klass) - klass.instance_eval { @__instance__ = nil } - class << klass - define_method(:instance,FirstInstanceCall) + + 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) + raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}" + end + super end - 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) - raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}" + + def included(klass) + super + klass.private_class_method :new, :allocate + klass.extend SingletonClassMethods + Singleton.__init__(klass) end - super end - def included(klass) - super - klass.private_class_method :new, :allocate - klass.extend SingletonClassMethods - Singleton.__init__(klass) - end end - if __FILE__ == $0 @@ -223,9 +178,9 @@ class << Ups def _instantiate? @enter.push Thread.current[:i] while false.equal?(@__instance__) - Thread.critical = false + @__mutex__.unlock sleep 0.08 - Thread.critical = true + @__mutex__.lock end @leave.push Thread.current[:i] @__instance__ |