Forum: Ruby-core WeakRef is unsafe to use in Ruby 1.9

Posted by uggsoutlet (uggsoutlet uggsoutlet) (Guest)
on 2012-11-22 07:30
(Received via mailing list)
Issue #4168 has been updated by uggsoutlet (uggsoutlet uggsoutlet).


=begin
would be an excellent rule. Such an attitude would emphasize  ((<uggs on 
sale|URL:http://www.gooduggboots.org/>)) sharply the value of life. 
Every day we should with gentleness, vigor, hold ((<cheap ugg 
boots|URL:http://www.gooduggboots.org/>)) the heart of thanksgiving to 
life. But when the time for endless days, months and years passed in 
((<uggs outlet|URL:http://www.gooduggboots.org/>)) front of us, we are 
often not the seed feeling. Of course, there is also " eat, drink, enjoy 
.458gyu854
=end
----------------------------------------
Feature #4168: WeakRef is unsafe to use in Ruby 1.9
https://bugs.ruby-lang.org/issues/4168#change-33472

Author: bdurand (Brian Durand)
Status: Closed
Priority: Normal
Assignee: nobu (Nobuyoshi Nakada)
Category: lib
Target version: 2.0.0


=begin
 I've found a couple issues with the implementation of WeakRef in Ruby 
1.9.

 1. WeakRef is unsafe to use because the ObjectSpace will recycle object 
ids for use with newly allocated objects after the old objects have been 
garbage collected. This problem was not present in 1.8, but with the 1.9 
threading improvements there is no guarantee that the garbage collector 
thread has finished running the finalizers before new objects are 
allocated. This can result in a WeakRef returning a different object 
than the one it originally referenced.

 2. In Ruby 1.9 a Mutex is used to synchronize access to the shared data 
structures. However, Mutexes are not reentrant and the finalizers are 
silently throwing deadlock errors if they run while new WeakRefs are 
being created.

 I've included in my patch a reimplementation of WeakRef called 
WeakReference that does not extend Delegator. This code is based on the 
original WeakRef code but has been rewritten so the variable names are a 
little clearer. It replaces the Mutex with a Monitor and adds an 
additional check to make sure that the object returned by the reference 
is the same one it originally referred to. WeakRef is rewritten as a 
Delegator wrapper around a WeakReference for backward compatibility.

 I went this route because in some Ruby implementations (like Ruby 1.8), 
Delegator is very heavy weight to instantiate and creating a collection 
of thousands of WeakRefs will be slow and use up far too much memory (in 
fact, it would be nice to either backport this patch to Ruby 1.8 or the 
delegate changes from 1.9 to 1.8 if possible). I also don't really see 
the value of having weak references be delegators since is very unsafe 
to do anything without wrapping the call in a "rescue RefError" block. 
The object can be reclaimed at any time so the only safe method to be 
sure you still have it is to create a strong reference to the object at 
which point you might as well use that reference instead of the 
delegated methods on the WeakRef. It also should be simpler for other 
implementations of Ruby like Jruby or Rubinius to map native weak 
references to a simpler interface.

 Sample code with WeakReference

     orig = Object.new
     ref = WeakReference.new(orig)
     # ...
     obj = ref.object
     if obj
       # Do something
     end

 I also have a version of the patch which just fixes WeakRef to work 
without introducing a new class, but I feel this version is the right 
way to go.

 Also included are unit tests for weak references but the test that 
checks for the broken functionality is not 100% reliable since garbage 
collection is not deterministic. I've also included a script that shows 
the problem in more detail with the existing weak reference 
implementation.

     ruby show_bug.rb 100000     # Run 100,000 iterations on the current 
implementation of WeakRef and report any problems
     ruby -I. show_bug.rb 100000 # Run 100,000 iterations on the new 
implementation of WeakRef and report any problems
=end
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.