Re: cdata finalizer called twice

  • From: Peter Colberg <peter@xxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Sun, 16 Nov 2014 02:03:05 -0500

Hi,

Finally I discovered why some cdata objects were finalized twice.

To query information about OpenCL objects, I use a common function

  local function get_info(obj_info)
    return function(obj, name)
      return obj_info[name](obj)
    end
  end

to generate dispatch closures for different sub-method tables, e.g.

  ffi.metatype("struct _cl_mem", __index = {
    get_info = get_info({
      type  = get_mem_object_info_type,
      flags = get_mem_object_info_flags,
      size  = get_mem_object_info_size,
    }),
  })

  ffi.metatype("struct _cl_event", __index = {
    get_profiling_info = get_info({
      queued  = get_event_profiling_info_queued,
      submit  = get_event_profiling_info_submit,
      start   = get_event_profiling_info_start,
      ["end"] = get_event_profiling_info_end,
    })
  })

Invoking both _cl_mem.get_info() and _cl_event.get_profiling_info()
within a loop results in undefined behaviour; in this case it may
cause duplicate finalization of '_cl_event *' objects.

Rewriting the object methods as follows resolves the issue:

  local mem_info = {
    type  = get_mem_object_info_type,
    flags = get_mem_object_info_flags,
    size  = get_mem_object_info_size,
  }

  ffi.metatype("struct _cl_mem", __index = {
    get_info = function(mem, name)
      return mem_info[name](mem)
    end,
  })

  local event_profiling_info = {
    queued  = get_event_profiling_info_queued,
    submit  = get_event_profiling_info_submit,
    start   = get_event_profiling_info_start,
    ["end"] = get_event_profiling_info_end,
  }

  ffi.metatype("struct _cl_event", __index = {
    get_profiling_info = function(event, name)
      return event_profiling_info[name](event)
    end,
  })

Is the undefined behaviour in the first case expected?

The documentation of ffi.metatype() states that the contents of the
metatable and the contents of the __index table may not be modified
afterwards. Does this include that methods in the __index tables of
different ctypes may not be closures created from the same function?

Peter

Other related posts: