Re: cdata finalizer called twice

  • From: Peter Colberg <peter@xxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 13 Nov 2014 14:51:51 -0500

On Thu, Nov 13, 2014 at 07:54:28PM +0100, Mike Pall wrote:
> ffi.gc() only attaches to the cdata pointer object you pass to it.
> Only the lifetime of this *object* decides when the finalizer is
> called. It doesn't matter which other pointers you have around
> that point to the same address.
> 
> Oh, and ... maybe you missed it, because my answer was so lengthy,
> but 'event' is unanchored. Anything can happen if you do that.

'event' is only a temporary array that receives the value that is then
used to construct the cdata object. The finalizer is attached to that
cdata object. Let me clarify the (non-self-contained) example:

  ffi.cdef[[
  typedef void *cl_event;
  ]]

  local function enqueue_marker(queue)
    local event_ptr = ffi.new("cl_event[1]")
    assert(C.CL_SUCCESS == C.clEnqueueMarker(queue, event_ptr))
    local event = ffi.new("cl_event", event_ptr[0])
    return ffi.gc(event, release_event)
  end

  local queue = ...
  for i = 1, 100000 do
    collectgarbage() -- sporadic duplicate finalization of previous event object
    local event = enqueue_marker(queue)
  end

Why is the finalizer sometimes called twice when cl_event is a pointer type?

Thanks,
Peter

Other related posts: