summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorPhillip J. Eby <pje@telecommunity.com>2006-04-10 17:51:05 (GMT)
committerPhillip J. Eby <pje@telecommunity.com>2006-04-10 17:51:05 (GMT)
commit2ba96610bfeda03381dd411d5694fae311159a0c (patch)
treea0007d4f0c9ee9bb38dbdef8311e7e0085708097 /Objects
parent17de8ffc215d8539860a8a7f06279c4155382c4f (diff)
downloadcpython-2ba96610bfeda03381dd411d5694fae311159a0c.zip
cpython-2ba96610bfeda03381dd411d5694fae311159a0c.tar.gz
cpython-2ba96610bfeda03381dd411d5694fae311159a0c.tar.bz2
SF Patch #1463867: Improved generator finalization to allow generators
that are suspended outside of any try/except/finally blocks to be garbage collected even if they are part of a cycle. Generators that suspend inside of an active try/except or try/finally block (including those created by a ``with`` statement) are still not GC-able if they are part of a cycle, however.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/genobject.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c
index e7b8f87..a3eae6a 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -5,6 +5,7 @@
#include "genobject.h"
#include "ceval.h"
#include "structmember.h"
+#include "opcode.h"
static int
gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
@@ -358,3 +359,22 @@ PyGen_New(PyFrameObject *f)
_PyObject_GC_TRACK(gen);
return (PyObject *)gen;
}
+
+int
+PyGen_NeedsFinalizing(PyGenObject *gen)
+{
+ int i;
+ PyFrameObject *f = gen->gi_frame;
+
+ if ((PyObject *)f == Py_None || f->f_stacktop==NULL || f->f_iblock<=0)
+ return 0; /* no frame or no blockstack == no finalization */
+
+ for (i=f->f_iblock; i>=0; i--) {
+ if (f->f_blockstack[i].b_type != SETUP_LOOP)
+ /* any block type besides a loop requires cleanup */
+ return 1;
+ }
+
+ /* No blocks except loops, it's safe to skip finalization */
+ return 0;
+}