diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2013-05-18 23:11:58 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2013-05-18 23:11:58 (GMT) |
commit | fef34e318697e53ea1b39a5da02308acdc5367f4 (patch) | |
tree | 8e0f466a86d5670014d783f222d497ad1bb144bc /Modules/gcmodule.c | |
parent | 20c1cdd64aba14cbe7a2484f4569f3e7e4e7132a (diff) | |
download | cpython-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.c | 31 |
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) |