GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||
GeezerVison is showing github.com — gh-113964: Don't prevent new threads until all non-daemon threads exit by colesbury · Pull Request #116677 · python/cpython Conversation
|
|
Thanks for looking at this! I'll leave it up to @gpshead to review. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
History of (1) June 2023, issue gh-104690: (2) Sept 2023, issue gh-108987: // gh-108987: If _thread.start_new_thread() is called before or while // Python is being finalized, thread_run() can called *after*. // _PyRuntimeState_SetFinalizing() is called. At this point, all Python // threads must exit, except of the thread calling Py_Finalize() whch holds // the GIL and must not exit. // // At this stage, tstate can be a dangling pointer (point to freed memory), // it's ok to call _PyThreadState_MustExit() with a dangling pointer. if (_PyThreadState_MustExit(tstate)) { // Don't call PyThreadState_Clear() nor _PyThreadState_DeleteCurrent(). // These functions are called on tstate indirectly by Py_Finalize() // which calls _PyInterpreterState_Clear(). // // Py_DECREF() cannot be called because the GIL is not held: leak // references on purpose. Python is being finalized anyway. thread_bootstate_free(boot, 0); goto exit; } (3) Feb 2024, gh-114570: I added With all these changes, I'm no longer sure what should be the correct behavior. I only hope that our test suite is now testing cases which caused crashes previously. I prefer to let someone else decide on this issue :-) The Python finalization is fragile. I took notes on old issues and the history of changes at: https://pythondev.readthedocs.io/finalization.html |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
In general I think this change is correct. I believe we'll want to backport this to 3.12 (I haven't looked at how difficult that'll be though) as the issue came up there as being a behavior regression from <=3.11 that reasonable code relies on.
One thing I think we're missing with the unit test transformations to be "AtFinalization" via the main interpreter exiting and triggering is: Alternate explicit tests for atexit.register()'d handlers at finalization time. Which implies we need to explicitly define what that behavior should be. But that may be a separate PR, i've noted that on the issue.
For this, see also #115219 which I may mark a dupe.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I created #116982 for atexit - please take a look at that. Keeping these separate makes sense, and yours should go in first. But it'll be an easier merge if the tests I build on are not removed if feasible. (otherwise no worries, i'll untangle it when merging into mine) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@gpshead - I don't see a way to avoid removing/replacing the atexit tests. The existing atexit tests would not pass with this PR (because the exception is not raised), and the atexit tests from your PR would not pass reliably without the other changes from your PR. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I will go ahead and merge this with apologies for the inevitable merge conflicts. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks @colesbury for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sorry, @colesbury, I could not cleanly backport this to |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
GH-117029 is a backport of this pull request to the 3.12 branch. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…n threads exit (pythonGH-116677) Starting in Python 3.12, we prevented calling fork() and starting new threads during interpreter finalization (shutdown). This has led to a number of regressions and flaky tests. We should not prevent starting new threads (or `fork()`) until all non-daemon threads exit and finalization starts in earnest. This changes the checks to use `_PyInterpreterState_GetFinalizing(interp)`, which is set immediately before terminating non-daemon threads. (cherry picked from commit 60e105c) Co-authored-by: Sam Gross <[email protected]>
…ads exit (GH-116677) (#117029) Starting in Python 3.12, we prevented calling fork() and starting new threads during interpreter finalization (shutdown). This has led to a number of regressions and flaky tests. We should not prevent starting new threads (or `fork()`) until all non-daemon threads exit and finalization starts in earnest. This changes the checks to use `_PyInterpreterState_GetFinalizing(interp)`, which is set immediately before terminating non-daemon threads. (cherry picked from commit 60e105c)
…ds exit (python#116677) Starting in Python 3.12, we prevented calling fork() and starting new threads during interpreter finalization (shutdown). This has led to a number of regressions and flaky tests. We should not prevent starting new threads (or `fork()`) until all non-daemon threads exit and finalization starts in earnest. This changes the checks to use `_PyInterpreterState_GetFinalizing(interp)`, which is set immediately before terminating non-daemon threads.
…ds exit (python#116677) Starting in Python 3.12, we prevented calling fork() and starting new threads during interpreter finalization (shutdown). This has led to a number of regressions and flaky tests. We should not prevent starting new threads (or `fork()`) until all non-daemon threads exit and finalization starts in earnest. This changes the checks to use `_PyInterpreterState_GetFinalizing(interp)`, which is set immediately before terminating non-daemon threads.
…ds exit (python#116677) Starting in Python 3.12, we prevented calling fork() and starting new threads during interpreter finalization (shutdown). This has led to a number of regressions and flaky tests. We should not prevent starting new threads (or `fork()`) until all non-daemon threads exit and finalization starts in earnest. This changes the checks to use `_PyInterpreterState_GetFinalizing(interp)`, which is set immediately before terminating non-daemon threads.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.