lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Didier escribió:

> thanks for your help,

> but frankly I've not really understood how the weak tables are working

> I guess the code I wrote is working for small amounts of data but
> I'm not sure of what would happened if several gc occured during the
> processing.

en respuesta a Adam Moss:

>> See section 2.9.1 of the manual.  __gc metamethods are
>> collected in reverse order of creation, for data that is collected
>> in the same gc cycle.  If you additionally want to ensure that one
>> userdata will always live at least as long as another, try using
>> a weak-keyed/valued table (see section 2.9.2).

This use of weak tables is probably not quite obvious from
the manual, although it is a useful idiom.

Without going into all of the theory, here is a solution
(unverified, let me know if there are any problems):

do 
  -- create a weak-keyed table
  local dependency_table = setmetatable({}, {__mode = "k"})

  -- The following function guarantees that {self} will be
  -- garbage collected after {other}.
 
  -- Both {other} and {self} should be one of the types
  -- {function}, {table}, {thread} or {fulluserdata};
  -- unfortunately there is no way of testing for this
  -- condition from a Lua script because {lightuserdata}
  -- and {fulluserdata} are indistinguishable.

  -- If {other} is {true}, a {number}, or a {string}, 
  -- {self} will not be garbage collected until the Lua
  -- state is closed. This might be useful; if so, I
  -- would suggest the use of {true}.

  -- If {self} is a {string} or a non-garbage-collectable
  -- object, this function will simply waste time and space.

  -- self = gcafter(self, other)
  function gcafter(self, other)
    if self and other then
      local depends = dependency_table[other]
      if not depends then 
        dependency_table[other] = {self, n=1}
       else
        table.insert(depends, self)
      end
    end
    return self
  end
end