lua-users home
lua-l archive

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



Mark Hamburg:

> If t is a weak table and I do the following:
>   for k, v in pairs( t )
>     -- do something that might trigger garbage collection
>     -- thereby eliminating some entries in t
>   end

> Do I risk having the iteration get fouled by having entries in the
> table get cleared? Fouled includes missing entries that don't get
> cleared.

No, there is no risk (at least no risk of corruption).

It is conceivable that while you are working on some particular
key/value pair, the iterator variable k (v) is the only strong
reference to that particular key (value). If a garbage collection
happens at that instant, the pair will be marked (and therefore
not cleared), because the local variable k holds a strong reference.
So that will delay (but not prevent) garbage collection of that pair.

The issue, really, is that the weak table may still contain pairs which
would have been cleared had garbage collection run; consequently, your
for loop may initiate methods on objects which are, in some sense,
moribund.

Even trying to count the number of pairs in the table is unpredictable
(although it will never be less than the number of "live" pairs).

> Should I bracket this with code to remove and restore the metatable
> for t?
> Will that work?

No, you shouldn't. Changing the weakness of a table once it has been
created is discouraged. You should only change table mode on a freshly
created table. (I would say the same thing about __gc methods on
userdata.)

You *might* want to manually trigger a garbage collection before
iterating the table; that will lower the probability of finding
moribund pairs (but since you could conceivably delete the last
reference to a key during the iteration, it still does not guarantee
that every key/value is "live").

In general, I would suggest not iterating over weak keyed tables because
of the unpredictability of the result (read: potential for unreproducible
bugs) but not because of any sense of unsafeness. (In fact, I am of the
opinion that weak-keyed tables should not be iterable -- but I may be
in a minority.) Weak-valued tables also present some oddities during
iteration, but they seem more controllable.

Rici