The following message is a courtesy copy of an article
that has been posted to comp.lang.misc as well.
I was playing with weak references, and came up with a problem with
garbage collection control. It goes something like this:
There are two ways to check for the validity of a weak reference.
1. Use it, and rescue a WeakRef::RefError exception
2. Check that it is valid using weakref_valid?
If I wanted to use weakref_valid?, and not exceptions, it seems to me
I'd have to disable GC around the use. In a single threaded program, I
could use something like:
ref = WeakRef.new(someObject)
# .. some time later
gcWasDisabled = GC.disable
if ref.weakref_alive?
# do stuff with 'ref'
end
GC.enable unless gcWasDisabled
(If I didn't disable GC, the weakref_valid? call could return 'true',
and then GC could delete the referenced object before the body of the
'if' executed.)
Now, in a multi-threaded environment, things get exciting. Because
other threads could also use the GC.xx methods to control garbage
collection, a simple local variable 'gcWasDisabled' no longer
works. Instead, I _think_ I'd have to modify the existing methods in
the GC module, making them thread safe, and having them maintain a
count which is incremented on disables and decremented on enables. The
original GC.enable would then only be called if this count reached
zero.
So... Am I making this too complicated? Is there an easier/better way
to control GC in a multi-threaded application? Or, alternatively,
should the nesting count be added to the existing GC module?
Regards
Dave