[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: GC order
- From: RLake@...
- Date: Thu, 8 May 2003 15:07:10 -0500
> You can do that. First, you must store the userdata in the coroutine
> (e.g., in its stack, or in its global table, if it has a separated
> global table). So, the userdata cannot be collected before the coroutine.
> Then, you must store an entry (userdata -> coroutine) in a table with
> weak keys (but strong values). That entry will not prevent the userdata
> from being collected. The main point here is that a weak key is only
> cleared *after* its __gc method runs. That means that, when the __gc
> method runs, you still can safely retrieve the coroutine from this
> table. (This is not by chance; it is the reason why weak keys are
> only cleared after running the __gc methods).
Sorry, Roberto, but that won't work. I have pointed this out a few times.
The weak table has a strong reference to the coroutine. Strong references
are marked and traversed. The coroutine has a reference to the userdata. So
the userdata is marked. So the reference to the coroutine is never deleted
from the weak table. Consequently neither the coroutine nor the userdata
will ever get collected.
See <http://lua-users.org/wiki/GarbageCollectingWeakTables>
gentoo lua-5.0 # bin/lua
Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio
> -- Create an object b
> b = {}
> -- Create a which refers to b
> a = {b}
> -- create a weaktable in which b points to a
> weak = setmetatable({}, {__mode = "k"})
> weak[b] = a
> -- Get rid of the only references to a and b other than the weak one
> a, b = nil, nil
> -- what's in the table?
> table.foreach(weak, print)
table: 0x8069e38 table: 0x806a0b8
> -- garbage collect a few times
> collectgarbage()
> collectgarbage()
> collectgarbage()
> collectgarbage()
> -- what's in the table?
> table.foreach(weak, print)
table: 0x8069e38 table: 0x806a0b8