Immediate closing of iterators
brendan at mozilla.org
Thu Dec 21 12:27:48 PST 2006
On Dec 21, 2006, at 12:04 PM, Chris Hansen wrote:
> In C#, as I understand it, they sidestep this problem by (I'll try to
> formulate this in terms of ES4) simply not allowing you to iterate
> over generators. You can iterate over objects with an iterator::get
> method but the returned object is owned by the loop and if it is a
> generator it will be closed on loop exit whether or not others have
> references to it.
That's not Pythonic, but it certainly is simple. I like it.
> Also, a generator doesn't have an iterator::get
> method since that would complicate the question of who "owns" it.
This is not a problem in the ES4 proposal, or in Python. Ownership
of storage and close are coupled only to guarantee that close happens
eventually, even if the client code fails to call gen.close()
explicitly. More below.
> That only "solves" Jeff's problem by disallowing it (ta-daa! ;-) but
> it does away with the need for any kind of finalization, prompt or
> not. In my experience (from java) GC finalization is something you
> want to steer well clear of.
Finalization is definitely two-phase in systems that have to support
close (which might resurrect the generator) and then release its
storage. Those of us burdened with GC-based memory management for ES/
JS/AS implementations have to dance with the GC here.
The extensions in SpiderMonkey were not pretty, but became better
after some over-general wrong turns were undone. The current code is
quite concrete: *only* generators participate in the close phase;
scheduling close operations requires cooperation from the browser
embedding, to prevent trivial Denial Of Service attacks (similar to
those possible already via setTimeout). IOW, a browser embedding may
cancel outstanding close ops in some cases (e.g., the document whose
script created the generator has been unloaded already).
For ref-counting implementations, there's still the possibility of a
reference cycle. So CPython, e.g., has to run close from its cycle
collector, if it didn't already get called by the client code.
CPython doesn't worry about DOSes from generators that resurrect
themselves or spawn more generators from their close hooks, AFAIK.
> What do you think?
It's a great simplifying change, but it doesn't avoid the need to add
a close protocol to one's GC, as noted above (there's no way around
that problem, so I'm not dinging your suggestion, just trying to
separate issues). I'll run it up the pole with SpiderMonkey hackers
and look for comments here from other ES4 parties.
More information about the Es4-discuss