diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-13 03:37:06 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-13 03:37:06 +0000 |
commit | df058ea0e3e13ad52fd3a3490b1e3bd56db044b2 (patch) | |
tree | e9e288a7d4d13a8259245a1dedc97e2f4c107ea2 /lib/weakref.rb | |
parent | 826cdd67a043b520c70cc9fcf66028603a130560 (diff) | |
download | ruby-df058ea0e3e13ad52fd3a3490b1e3bd56db044b2.tar.gz |
Bug #5350
* gc.c: add ObjectSpace::WeakMap. [ruby-dev:44565][Bug #5350]
* lib/weakref.rb: use WeakMap instead of _id2ref.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34995 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/weakref.rb')
-rw-r--r-- | lib/weakref.rb | 48 |
1 files changed, 10 insertions, 38 deletions
diff --git a/lib/weakref.rb b/lib/weakref.rb index ee5444a584..78f88a3f12 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -1,5 +1,4 @@ require "delegate" -require 'thread' # Weak Reference class that allows a referenced object to be # garbage-collected. A WeakRef may be used exactly like the object it @@ -24,51 +23,24 @@ class WeakRef < Delegator class RefError < StandardError end - @@id_map = {} # obj -> [ref,...] - @@id_rev_map = {} # ref -> obj - @@mutex = Mutex.new - @@final = lambda {|id| - @@mutex.synchronize { - rids = @@id_map[id] - if rids - for rid in rids - @@id_rev_map.delete(rid) - end - @@id_map.delete(id) - end - rid = @@id_rev_map[id] - if rid - @@id_rev_map.delete(id) - @@id_map[rid].delete(id) - @@id_map.delete(rid) if @@id_map[rid].empty? - end - } - } + @@__map = ::ObjectSpace::WeakMap.new ## # Creates a weak reference to +orig+ def initialize(orig) - @__id = orig.object_id - ObjectSpace.define_finalizer orig, @@final - ObjectSpace.define_finalizer self, @@final - @@mutex.synchronize { - @@id_map[@__id] = [] unless @@id_map[@__id] - } - @@id_map[@__id].push self.object_id - @@id_rev_map[self.object_id] = @__id + case orig + when true, false, nil + @delegate_sd_obj = orig + else + @@__map[self] = orig + end super end def __getobj__ # :nodoc: - unless @@id_rev_map[self.object_id] == @__id - Kernel::raise RefError, "Invalid Reference - probably recycled", Kernel::caller(2) - end - begin - ObjectSpace._id2ref(@__id) - rescue RangeError - Kernel::raise RefError, "Invalid Reference - probably recycled", Kernel::caller(2) - end + @@__map[self] or defined?(@delegate_sd_obj) ? @delegate_sd_obj : + Kernel::raise(RefError, "Invalid Reference - probably recycled", Kernel::caller(2)) end def __setobj__(obj) # :nodoc: @@ -78,7 +50,7 @@ class WeakRef < Delegator # Returns true if the referenced object is still alive. def weakref_alive? - @@id_rev_map[self.object_id] == @__id + !!(@@__map[self] or defined?(@delegate_sd_obj)) end end |