summaryrefslogtreecommitdiffstats
path: root/Modules/gcmodule.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2013-05-18 23:11:58 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2013-05-18 23:11:58 (GMT)
commitfef34e318697e53ea1b39a5da02308acdc5367f4 (patch)
tree8e0f466a86d5670014d783f222d497ad1bb144bc /Modules/gcmodule.c
parent20c1cdd64aba14cbe7a2484f4569f3e7e4e7132a (diff)
downloadcpython-fef34e318697e53ea1b39a5da02308acdc5367f4.zip
cpython-fef34e318697e53ea1b39a5da02308acdc5367f4.tar.gz
cpython-fef34e318697e53ea1b39a5da02308acdc5367f4.tar.bz2
Issue #17937: Try harder to collect cyclic garbage at shutdown.
Diffstat (limited to 'Modules/gcmodule.c')
-rw-r--r--Modules/gcmodule.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 4315d55..28417c2 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -853,7 +853,8 @@ get_time(void)
/* This is the main function. Read this to understand how the
* collection process works. */
static Py_ssize_t
-collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable)
+collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable,
+ int nofail)
{
int i;
Py_ssize_t m = 0; /* # objects collected */
@@ -1000,10 +1001,15 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable)
}
if (PyErr_Occurred()) {
- if (gc_str == NULL)
- gc_str = PyUnicode_FromString("garbage collection");
- PyErr_WriteUnraisable(gc_str);
- Py_FatalError("unexpected exception during garbage collection");
+ if (nofail) {
+ PyErr_Clear();
+ }
+ else {
+ if (gc_str == NULL)
+ gc_str = PyUnicode_FromString("garbage collection");
+ PyErr_WriteUnraisable(gc_str);
+ Py_FatalError("unexpected exception during garbage collection");
+ }
}
/* Update stats */
@@ -1062,7 +1068,7 @@ collect_with_callback(int generation)
{
Py_ssize_t result, collected, uncollectable;
invoke_gc_callback("start", generation, 0, 0);
- result = collect(generation, &collected, &uncollectable);
+ result = collect(generation, &collected, &uncollectable, 0);
invoke_gc_callback("stop", generation, collected, uncollectable);
return result;
}
@@ -1544,6 +1550,19 @@ PyGC_Collect(void)
return n;
}
+Py_ssize_t
+_PyGC_CollectNoFail(void)
+{
+ Py_ssize_t n;
+
+ /* This function should only be called on interpreter shutdown, and
+ therefore not recursively. */
+ assert(!collecting);
+ collecting = 1;
+ n = collect(NUM_GENERATIONS - 1, NULL, NULL, 1);
+ collecting = 0;
+ return n;
+}
void
_PyGC_DumpShutdownStats(void)