Finalizers...

M

Michael Neumann

Hi,

Are finalizers (ObjectSpace.define_finalizer) executed atomicly? Or can
they be interrupt by other finalizers (or threads)?

I've noticed that finalizers can't raise exceptions. They silently
abort. That's a feature, but hard to find bugs in finalizers ;-)

Regards,

Michael
 
C

Carlos

Hi,

Are finalizers (ObjectSpace.define_finalizer) executed atomicly? Or can
they be interrupt by other finalizers (or threads)?

There are run with Thread.critical=true.

------------------------------------------------------ Thread::critical=
Thread.critical= boolean => true or false
------------------------------------------------------------------------
Sets the status of the global ``thread critical'' condition and
returns it. When set to +true+, prohibits scheduling of any
existing thread. Does not block new threads from being created and
run. Certain thread operations (such as stopping or killing a
thread, sleeping in the current thread, and raising an exception)
may cause a thread to be scheduled even when in a critical section.
+Thread::critical+ is not intended for daily use: it is primarily
there to support folks writing threading libraries.

Hope this helps.
 
P

Paul Brannan

Are finalizers (ObjectSpace.define_finalizer) executed atomicly? Or can
they be interrupt by other finalizers (or threads)?

I believe finalizers are only called from the garbage collector, and the
garbage collector doesn't do anything if called re-entrantly.

Also, as Carlos pointed out, finalizers are run with
Thread#critical=true, so they won't be interrupted by another thread nor
will they be interrupted by a timeout.

I think that covers all the cases, except if you explicitly call the
finalizer proc yourself.

Paul
 
M

Michael Neumann

Paul said:
I believe finalizers are only called from the garbage collector, and the
garbage collector doesn't do anything if called re-entrantly.

hm, if you allocate objects inside the finalizer, the garbage collector
could be invoked while we're *in* the finalizer.

def run
p2 = proc { puts "fin" }

obj = Object.new
ObjectSpace.define_finalizer(obj, proc {
puts "enter obj"
loop do
x = Array.new
ObjectSpace.define_finalizer(x, p2)
end
puts "leave obj"
})
end

run

outputs:

enter obj
fin
fin
 
P

Paul Brannan

hm, if you allocate objects inside the finalizer, the garbage collector
could be invoked while we're *in* the finalizer.

Oh, my bad. The during_gc flag is cleared before the finalizers are
invoked.

Paul
 
M

Mark Hubbart

Hi,

Hi,

Are finalizers (ObjectSpace.define_finalizer) executed atomicly? Or can
they be interrupt by other finalizers (or threads)?

I've noticed that finalizers can't raise exceptions. They silently
abort. That's a feature, but hard to find bugs in finalizers ;-)

% ruby <<EOP
f = lambda do
begin
0/0
rescue ZeroDivisionError => e
puts e, e.backtrace
end
end
ObjectSpace.define_finalizer "foo", f
EOP
divided by 0
-:3:in `/'
-:3
-:1:in `call'
-:8

One could imagine an ObjectSpace.define_debug_finalizer:

### untested ###
def ObjectSpace.define_debug_finalizer(obj, callable, io = STDERR)
wrapper = lambda do |id|
begin
callable.call(id)
rescue Exception=>e
io.puts e, e.backtrace
end
end
ObjectSpace.define_finalizer obj, wrapper
end

cheers,
Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,427
Latest member
HildredDic

Latest Threads

Top