Class: Ref::ReferenceQueue
- Inherits:
-
Object
- Object
- Ref::ReferenceQueue
- Defined in:
- lib/ref/reference_queue.rb
Overview
This class provides a simple thread safe container to hold a reference queue. Instances of WeakReference can be added to the queue and as the objects pointed to by those references are cleaned up by the garbage collector, the references will be added to the queue.
The reason for using a reference queue is that it tends to be more efficient than adding individual finalizers to objects and the cleanup code can be handled by a thread outside of garbage collection.
In general, you should create your own subclass of WeakReference that contains the logic needed to complete the cleanup. The object pointed to will have already been cleaned up and the reference cannot maintain a reference to the object.
Example usage:
class MyRef < Ref::WeakReference
def cleanup
# Do something...
end
end
queue = Ref::ReferenceQueue.new
ref = MyRef.new(Object.new)
queue.monitor(ref)
queue.shift # = nil
ObjectSpace.garbage_collect
r = queue.shift # = ref
r.cleanup
Instance Method Summary collapse
-
#empty? ⇒ Boolean
Return
true
if the queue is empty. -
#initialize ⇒ ReferenceQueue
constructor
A new instance of ReferenceQueue.
-
#monitor(reference) ⇒ Object
Monitor a reference.
-
#pop ⇒ Object
Pull the last reference off the queue.
-
#push(reference) ⇒ Object
Add a reference to the queue.
-
#shift ⇒ Object
Pull the next reference off the queue.
-
#size ⇒ Object
Get the current size of the queue.
Constructor Details
#initialize ⇒ ReferenceQueue
Returns a new instance of ReferenceQueue.
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/ref/reference_queue.rb', line 30 def initialize @queue = [] @references = {} @lock = SafeMonitor.new @finalizer = lambda do |object_id| @lock.synchronize do ref = @references.delete(object_id) @queue.push(ref) if ref end end end |
Instance Method Details
#empty? ⇒ Boolean
Return true
if the queue is empty.
80 81 82 |
# File 'lib/ref/reference_queue.rb', line 80 def empty? @queue.empty? end |
#monitor(reference) ⇒ Object
Monitor a reference. When the object the reference points to is garbage collected, the reference will be added to the queue.
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/ref/reference_queue.rb', line 44 def monitor(reference) obj = reference.object if obj @lock.synchronize do @references[reference.referenced_object_id] = reference end ObjectSpace.define_finalizer(obj, @finalizer) else push(reference) end end |
#pop ⇒ Object
Pull the last reference off the queue. Returns nil
if their are no references.
66 67 68 69 70 |
# File 'lib/ref/reference_queue.rb', line 66 def pop @lock.synchronize do @queue.pop end end |
#push(reference) ⇒ Object
Add a reference to the queue.
57 58 59 60 61 62 63 |
# File 'lib/ref/reference_queue.rb', line 57 def push(reference) if reference @lock.synchronize do @queue.push(reference) end end end |
#shift ⇒ Object
Pull the next reference off the queue. Returns nil
if there are no references.
73 74 75 76 77 |
# File 'lib/ref/reference_queue.rb', line 73 def shift @lock.synchronize do @queue.shift end end |
#size ⇒ Object
Get the current size of the queue.
85 86 87 |
# File 'lib/ref/reference_queue.rb', line 85 def size @queue.size end |