[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Weak tables and userdata finalization
- From: Mark Hamburg <mark@...>
- Date: Thu, 15 Sep 2011 07:35:08 -0700
On Sep 15, 2011, at 6:57 AM, Roberto Ierusalimschy wrote:
>> Maybe I just confirmed my original theory and demonstrated that my
>> recollection was wrong:
>> udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
>> marktmu(g); /* mark `preserved' userdata */
>> udsize += propagateall(g); /* remark, to propagate `preserveness' */
>> cleartable(g->weak); /* remove collected objects from weak tables */
>> Basic lesson: Weak tables plus finalization are a dangerous mix?
> Certainly this basic lesson is correct.
> Nevertheless, if you did not find a bug, at least it seems an
> inconsistency. Anything anchored through finalizing userdata should have
> the same behavior (related to weak tables) of those userdata. Maybe
> Lua should clear tables with weak values before marking userdata to be
> finalized. (With that change, it seems that function 'iscleared' would
> not need to treat finalized userdata in keys as a special case.)
That would be more consistent in the behavior. As you might guess from this thread, it was a bit of a puzzle figuring out how we got burned since direct references in weak tables did get cleared.
That said, doing so would mean that userdata that needed to access other data would have to use the userdata environment rather than weak tables, so it's going to break some code out there that failed to adopt environments as the mechanism of choice. On the other hand, since semi-weak tables in Lua 5.1 are prone to GC cycles, they were a bad way to handle attaching Lua data to userdata anyway so breaking that code is probably for the best assuming it leads to it getting fixed. What's more, breaking it in this way won't introduce subtle errors since data one expected to be there suddenly won't be.
If I don't care about that change in semantics, is the minimal change to Lua 5.1 to move the cleartable call above the marktmu call? I've got my two-stage, weak-reference solution but a more robust -- i.e., less dependent on code doing "the right thing" -- solution seems desirable.