Subject: [ruby-ffi] AutoPointer#free incorrect? |
From: cfis |
Date: 8/30/11 2:24 AM |
To: ruby-ffi |
Unless I'm missing something, it looks to me that the implementation
of #free is not correct. I am wrapping FreeImage and have code like
this:
class Bitmap
def self.release(ptr) #:nodoc:
FreeImage.FreeImage_Unload(ptr)
end
end
Now I load an image:
bitmap = load_some_bitmap
In time it will get GC'ed, but let's say I want to force the issue:
bitmap.free
That calls AutoPointer#free
def free
@releaser.free
end
Which in turn calls Releaser#free:
def free
raise RuntimeError.new("pointer already freed") unless @ptr
@autorelease = false
@ptr = nil
@proc = nil
end
Notice that the bitmap was not freed. Worse, the bitmap will never be
freed because @autorelease is now false. Take a look at the finalizer:
class DefaultReleaser < Releaser
def call(*args)
@proc.release(@ptr) if @autorelease && @ptr
end
end
I think the free method should be:
def free
raise RuntimeError.new("pointer already freed") unless @ptr
@proc.release(@ptr)
@autorelease = false
@ptr = nil
@proc = nil
end
Thanks,
Charlie