lua-users home
lua-l archive

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

Am 28.08.2015 um 09:48 schröbte Dirk Laurie:
Was there near-universal acclaim for per-value metatables,
or am I just remembering what I like to? Anyway, pointing out
one more advantage can't hurt :-)

When a coroutine goes dead, there is often some finalizing to do.
Setting a return hook in order to call a finalizer looks kludgy.
The neat way is a __gc metamethod.

Two ways of calling finalizers for coroutines in Lua 5.2+ without hooks:

    local function mycocreate1( func, gc )
      local fin = setmetatable( { thread = false }, { __gc = gc } )
      local t = coroutine.create( function( ... )
        local finalizer = fin -- keep finalizer as an upvalue
        return func( ... )
      end )
      fin.thread = t
      return t

    local threadgcs = setmetatable( {}, { __mode = "k" } )

    local function mycocreate2( func, gc )
      local t = coroutine.create( func )
      threadgcs[ t ] = setmetatable( { thread = t }, { __gc = gc } )
      return t

    local function gc( t )
      print( t.thread )

      local t1 = mycocreate1( function() end, gc )
      local t2 = mycocreate2( function() end, gc )
      collectgarbage() collectgarbage()
      print( "xxx" )
    collectgarbage() collectgarbage()
    print( "yyy" )

That said, coroutines are GCObjects already, and a fresh coroutine costs about 1K of memory, so the extra 8 bytes for a metatable pointer doesn't really hurt.